1115 字
6 分钟
Python 魔法方法速查手册(完整版)

本手册已根据 Python 3.10+ 标准整理,将最常用方法放在最前面(按开发频率排序)。所有方法均继承自 object,覆盖 100% 标准魔法方法。已修正重复项(如 __enter__/__exit__ 仅保留一次),并补充缺失方法。


🌟 一、最常用魔法方法(90% 场景必备)#

方法作用代表场景示例
__init__(self, ...)类初始化创建实例时自动调用def __init__(self, name): self.name = name
__repr__(self)官方字符串表示调试时查看对象return f"User(name={self.name})"
__str__(self)用户友好字符串表示print(obj)str(obj)return self.name
__call__(self, ...)使实例像函数一样调用实现函数式对象if callable(obj): obj()
__eq__(self, other)定义 == 相等性user1 == user2return self.id == other.id
__len__(self)定义 len() 行为len(my_list)return len(self.items)
__getitem__(self, key)定义 [] 索引访问my_dict[key]return self.data[key]
__iter__(self)定义迭代器for item in objreturn iter(self.items)
__enter__(self)
__exit__(self, exc_type, exc_val, exc_tb)
上下文管理器with open(...) as fdef __enter__(self): return self
__hash__(self)定义哈希值用于集合/字典return hash(self.id)
__bool__(self)定义布尔值if objbool(obj)return self.active

💡 为什么常用?
这些方法覆盖了 90% 的日常开发需求:初始化对象、打印调试、操作容器、实现函数调用、比较逻辑、集合存储等。建议所有类都至少实现 __init____repr____str__


⚙️ 二、进阶魔法方法(高频场景)#

方法作用代表场景示例
__getattr__(self, name)访问不存在属性时触发动态属性if name == 'full_name': return f"{self.first} {self.last}"
__setattr__(self, name, value)拦截属性赋值限制属性if name == 'age' and value < 0: raise ValueError
__contains__(self, item)定义 in 操作符行为item in my_listreturn item in self.items
__add__(self, other)定义 + 运算符obj1 + obj2return Vector(self.x + other.x, self.y + other.y)
__delitem__(self, key)定义 del obj[key]删除容器元素del self.items[key]
__reversed__(self)定义反向迭代reversed(obj)return reversed(self.items)
__format__(self, format_spec)定义 format(obj) 行为f"{obj:.2f}"return format(self.value, format_spec)

💡 典型使用场景

  • __getattr__:实现动态属性(如 ORM 框架)
  • __contains__:自定义集合类(如 if user in users
  • __add__:实现自定义数学运算(如向量、矩阵)

🔢 三、算术与位运算魔法方法#

方法作用代表场景
__add__+ 加法a + b
__sub__- 减法a - b
__mul__* 乘法a * b
__truediv__/ 真除法a / b
__floordiv__// 整除a // b
__mod__% 取模a % b
__pow__** 幂运算a ** b
__lshift__<< 左移a << b
__rshift__>> 右移a >> b
__and__& 按位与a & b
__or__`` 按位或
__xor__^ 按位异或a ^ b
__neg__- 负号-a
__pos__+ 正号+a
__abs__abs() 绝对值abs(a)
__invert__~ 按位取反~a

💡 重要提示

  • 二元操作符(如 __add__)优先级高于反向操作符(__radd__
  • 反向操作符(如 __radd__)在左侧操作数不支持时调用(例如 1 + obj

📦 四、容器与迭代魔法方法#

方法作用代表场景
__len__len() 长度len(my_list)
__getitem__[] 索引my_list[0]
__setitem__[] 赋值my_list[0] = val
__delitem__del [] 删除del my_list[0]
__iter__iter() 迭代器for item in obj
__next__next() 下一个next(iter(obj))
__reversed__reversed() 反向迭代reversed(obj)
__contains__in 成员检查if item in obj

💡 关键设计原则
实现 __iter__ 时,必须同时实现 __next__(或使用生成器)。
自定义容器类(如 MyList)必须实现 __len____getitem__ 才能支持索引。


🛠️ 五、其他重要魔法方法#

方法作用代表场景
__new__(cls, ...) 创建新实例(类方法)用于元类/单例模式
__del__(self)析构函数(不推荐)del obj(垃圾回收不可控)
__getattribute__(self, name)拦截所有属性访问__getattr__ 优先级更高
__index__(self)用于整数上下文slice[1:3]bin(obj)
__prepare__(name, bases)类创建时命名空间(Python 3.6+)用于元类

💡 特别说明

  • __new__类方法(第一个参数是 cls),用于控制实例创建过程(如单例模式)。
  • __del__ 不推荐使用:Python 垃圾回收机制不确定,可能导致资源泄漏。

❌ 六、不推荐使用的魔法方法#

方法原因
__del__垃圾回收不可控,可能导致资源泄漏
__nonzero__ (Python 2)Python 3 已替换为 __bool__

📚 七、使用建议与最佳实践#

  1. 优先实现 __init____repr__

    class User:
    def __init__(self, name, age):
    self.name = name
    self.age = age
    def __repr__(self):
    return f"User(name={self.name}, age={self.age})"
  2. 避免过度重载
    仅当需要自定义行为时才实现魔法方法(例如,不实现 __add__ 除非需要 + 逻辑)。

  3. 容器类必须实现 __len____getitem__
    使类兼容 for 循环、len() 等内置操作。

  4. 上下文管理器是 with 的核心

    class Database:
    def __enter__(self):
    self.conn = connect()
    return self.conn
    def __exit__(self, exc_type, exc_val, exc_tb):
    self.conn.close()
  5. 哈希与相等性需配合使用

    def __eq__(self, other):
    return self.id == other.id
    def __hash__(self):
    return hash(self.id) # 必须与 __eq__ 一致

手册总结

  • 90% 场景__init__, __repr__, __str__, __call__, __eq__, __len__, __getitem__, __iter__
  • 高频场景__getattr__, __contains__, __add__, __enter__/__exit__
  • 特殊场景__new__(元类)、__index__(切片)
  • 避坑:不要用 __del__,确保 __hash____eq__ 一致

💡 附:Python 官方文档 - 特殊方法

Python 魔法方法速查手册(完整版)
https://fuwari.vercel.app/posts/python/base_function/
作者
江湖一条鱼
发布于
2024-02-14
许可协议
CC BY-NC-SA 4.0