"魔法"方法
Python 中的魔法方法(Magic Methods) 是以双下划线开头和结尾的特殊方法(例如 __init__
, __str__
),用于定义类的特定行为(如运算符重载、迭代、上下文管理等)。
__init__() 方法
__init__() 方法,在创建一个对象时默认被调用,不需要手动调用
__init__(self) 中,默认有1 个参数名字为 self ,如果在创建对象时传递了 2 个实参,那么 __init__(self) 中出了 self作为第一个形参外还需要 2 个形参,例如 __init__(self,x,y)
__str__(self) 方法
__str__(self) 方法,当使用print 输出对象的时候,只要自己定义了 __str__(self) 方法,那么就会打印从在这个方法中 return 的数据
作用、调用和命名
-
核心作用:魔法方法让自定义类具备与内置类型一致的行为。
-
调用方式:通常由 Python 解释器隐式调用(如
a + b
触发__add__
)。 -
命名规范:严格遵循双下划线开头和结尾的格式(如
__xxx__
)。
最佳实践
-
优先实现必要的魔法方法(如
__init__
,__str__
)。 -
保持行为一致性:例如,实现
__eq__
时最好同时实现__hash__
。 -
避免滥用运算符重载,确保操作符行为符合直觉。
常见的魔法方法分类及说明:
1. 初始化与构造
方法 说明 示例 __new__(cls, ...)
创建实例时调用(先于 __init__
),返回实例对象。obj = MyClass()
__init__(self, ...)
初始化实例属性,构造对象时调用。 def __init__(self, x): self.x = x
__del__(self)
对象被销毁时调用(垃圾回收触发)。 del obj
2. 运算符重载
方法 对应的运算符或操作 示例 __add__(self, other)
+
a + b
→a.__add__(b)
__sub__(self, other)
-
a - b
→a.__sub__(b)
__mul__(self, other)
*
a * b
→a.__mul__(b)
__eq__(self, other)
==
a == b
→a.__eq__(b)
__lt__(self, other)
<
a < b
→a.__lt__(b)
__str__(self)
定义对象的字符串表示(供 print()
或str()
使用)。print(obj)
→ 调用obj.__str__()
__repr__(self)
定义对象的官方字符串表示(供 repr()
或交互式环境显示)。repr(obj)
→obj.__repr__()
__bool__(self)
定义对象的布尔值( if obj:
时触发)。if obj:
→obj.__bool__()
3. 容器类行为
方法 说明 示例 __len__(self)
返回容器长度( len(obj)
时调用)。len(obj)
→obj.__len__()
__getitem__(self, key)
获取元素( obj[key]
时调用)。obj[0]
→obj.__getitem__(0)
__setitem__(self, key, value)
设置元素( obj[key] = value
时调用)。obj[0] = 5
→obj.__setitem__(0, 5)
__iter__(self)
返回迭代器对象( for x in obj
时调用)。iter(obj)
→obj.__iter__()
__next__(self)
迭代时获取下一个值(需与 __iter__
配合使用)。next(iter(obj))
__contains__(self, item)
检查是否包含元素( item in obj
时调用)。5 in obj
→obj.__contains__(5)
4. 上下文管理
方法 说明 示例 __enter__(self)
进入上下文时调用( with
语句开始时)。with obj as x:
→obj.__enter__()
__exit__(self, exc_type, exc_val, traceback)
退出上下文时调用(清理资源)。 with
块结束后调用
5. 属性访问与描述符
方法 说明 示例 __getattr__(self, name)
访问不存在的属性时调用。 obj.x
(若x
不存在)__setattr__(self, name, value)
设置属性时调用。 obj.x = 5
→obj.__setattr__('x', 5)
__delattr__(self, name)
删除属性时调用。 del obj.x
→obj.__delattr__('x')
__getattribute__(self, name)
访问任何属性时调用(优先级高于 __getattr__
)。obj.x
→obj.__getattribute__('x')
__dir__(self)
返回对象的属性列表( dir(obj)
时调用)。dir(obj)
→obj.__dir__()
6. 描述符协议(用于自定义属性行为)
方法 说明 __get__(self, instance, owner)
获取属性值时调用(用于描述符类)。 __set__(self, instance, value)
设置属性值时调用(用于描述符类)。 __delete__(self, instance)
删除属性时调用(用于描述符类)。
7. 反射与自省
方法 说明 __instancecheck__(self, instance)
自定义 isinstance(instance, cls)
的行为。__subclasscheck__(self, subclass)
自定义 issubclass(subclass, cls)
的行为。
8. 数值类型扩展
方法 说明 __int__(self)
定义对象转换为整数时的行为( int(obj)
)。__float__(self)
定义对象转换为浮点数时的行为( float(obj)
)。__complex__(self)
定义对象转换为复数时的行为。
9. 协程与异步
方法 说明 __await__(self)
定义异步迭代器的行为( async for
中使用)。__aiter__(self)
返回异步迭代器对象( async for
时调用)。__anext__(self)
异步迭代时获取下一个值。
其他重要方法
方法 说明 __call__(self, ...)
允许实例像函数一样被调用( obj()
时触发)。__slots__
限制类实例的属性(节省内存)。 __hash__(self)
定义对象的哈希值( hash(obj)
时调用,用于字典键或集合元素)。