魔法函数
在 Python 中,魔法函数(也称为特殊方法或双下划线方法)是一些具有特定命名模式的函数,它们以双下划线开头和结尾,如 __init__
、__str__
等。这些函数通常由 Python 解释器自动调用,用于实现一些特殊的行为。魔法函数允许你在自定义类中定义如何处理内置操作符、类型转换、迭代、上下文管理等。
常见的魔法函数
1. 构造与析构
-
__init__(self, ...)
: 构造函数,在创建对象时被调用,用于初始化对象的属性。class MyClass: def __init__(self, name): self.name = name
-
__del__(self)
: 析构函数,在对象被销毁时调用,用于清理资源。一般不常用。class MyClass: def __del__(self): print(f"Object {self.name} is being deleted")
2. 字符串表示
-
__str__(self)
: 定义对象的字符串表示,str()
或print()
函数调用时使用。class MyClass: def __init__(self, name): self.name = name def __str__(self): return f"MyClass object with name {self.name}" obj = MyClass("Example") print(obj) # 输出 "MyClass object with name Example"
-
__repr__(self)
: 定义对象的正式字符串表示,repr()
或在解释器中直接调用对象时使用,通常用于调试。class MyClass: def __init__(self, name): self.name = name def __repr__(self): return f"MyClass(name={self.name})" obj = MyClass("Example") print(obj) # 输出 "MyClass(name=Example)"
-
对象中同时有
__str__(self)
和__repr__(self)
时,优先调用__str__(self)
函数class MyClass: def __init__(self, name): self.name = name def __str__(self): return f"MyClass: __str__" def __repr__(self): return f"MyClass: __repr__" obj = MyClass("Example") print(obj) # 输出 "MyClass: __str__"
-
在python 控制台中只会调用
__repr__(self)
函数>>> from test01 import MyClass >>> obj = MyClass("Example") >>> obj MyClass: __repr__
3. 算术运算符重载
__add__(self, other)
: 实现加法操作 (+
)。__sub__(self, other)
: 实现减法操作 (-
)。__mul__(self, other)
: 实现乘法操作 (*
)。__truediv__(self, other)
: 实现除法操作 (/
)。__mod__(self, other)
: 实现取模操作 (%
)。
例如,实现向量加法:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Vector(self.x + other.x, self.y + other.y)
def __repr__(self):
return f"Vector({self.x}, {self.y})"
v1 = Vector(2, 3)
v2 = Vector(4, 5)
print(v1 + v2) # 输出 "Vector(6, 8)"
4. 比较运算符重载
__eq__(self, other)
: 实现等于 (==
)。__ne__(self, other)
: 实现不等于 (!=
)。__lt__(self, other)
: 实现小于 (<
)。__le__(self, other)
: 实现小于等于 (<=
)。__gt__(self, other)
: 实现大于 (>
)。__ge__(self, other)
: 实现大于等于 (>=
)。
例如,实现比较两个对象是否相等:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.name == other.name and self.age == other.age
p1 = Person("Alice", 30)
p2 = Person("Alice", 30)
print(p1 == p2) # 输出 True
5. 容器相关的魔法函数
-
__len__(self)
: 返回对象的长度,len()
函数调用时使用。class MyList: def __init__(self, items): self.items = items def __len__(self): return len(self.items) my_list = MyList([1, 2, 3]) print(len(my_list)) # 输出 3
-
__getitem__(self, key)
: 实现索引访问 ([]
)。class MyList: def __init__(self, items): self.items = items def __getitem__(self, index): return self.items[index] my_list = MyList([1, 2, 3]) print(my_list[1]) # 输出 2
-
__setitem__(self, key, value)
: 实现索引赋值 ([] =
)。class MyList: def __init__(self, items): self.items = items def __setitem__(self, key, value): self.items[key] = value my_list = MyList([1, 2, 3]) my_list[0] = 0 print(my_list.items) # 输出 [0, 2, 3]
-
__delitem__(self, key)
: 实现索引删除 (del[]
)。 -
__contains__(self, item)
: 实现成员测试 (in
)。
6. 迭代相关的魔法函数
-
__iter__(self)
: 返回一个迭代器对象,支持for
循环。class MyList: def __init__(self, items): self.items = items def __iter__(self): return iter(self.items) my_list = MyList([1, 2, 3]) for item in my_list: print(item) # 输出 1, 2, 3
-
__next__(self)
: 返回迭代器的下一个元素,用于自定义迭代器。class MyCounter: def __init__(self, start, end): self.current = start self.end = end def __iter__(self): return self # 返回自身作为迭代器对象 def __next__(self): if self.current > self.end: # 达到上限,停止迭代 raise StopIteration else: self.current += 1 return self.current - 1 # 返回当前值并递增 # 创建一个从 1 到 5 的计数器 counter = MyCounter(1, 5) # 使用 for 循环迭代计数器 for num in counter: print(num)
:输出结果
1 2 3 4 5
7. 上下文管理
__enter__(self)
: 定义上下文管理器的进入行为,支持with
语句。__exit__(self, exc_type, exc_value, traceback)
: 定义上下文管理器的退出行为。
例如,使用上下文管理器管理文件资源:
class MyContext:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("Exiting the context")
with MyContext():
print("Inside the context")
输出:
Entering the context
Inside the context
Exiting the context
8. 其他常见魔法函数
-
__call__(self, *args, **kwargs)
: 使对象像函数一样被调用。class MyClass: def __call__(self, x): return x * 2 obj = MyClass() print(obj(5)) # 输出 10
-
__bool__(self)
: 定义对象的布尔值转换,bool()
或条件表达式中使用。class MyClass: def __init__(self, value): self.value = value def __bool__(self): return bool(self.value) obj = MyClass(0) print(bool(obj)) # 输出 False