Python 中的魔术方法(Magic Methods),也称为双下划线方法(Dunder Methods),是特殊的方法,允许对象与内置函数和操作符进行交互。以下是一些常见的魔术方法及其功能详解:
1. 初始化与表示
__init__(self, ...)
:对象的初始化方法,当对象被创建时调用。__new__(cls, ...)
:创建并返回一个新的实例。一般很少重写,除非需要控制实例的创建过程。__del__(self)
:对象被删除时调用的方法。__repr__(self)
:返回对象的官方字符串表示,用于调试。__str__(self)
:返回对象的用户友好字符串表示。
2. 比较操作
__eq__(self, other)
:定义相等操作符==
的行为。__ne__(self, other)
:定义不等操作符!=
的行为。__lt__(self, other)
:定义小于操作符<
的行为。__le__(self, other)
:定义小于等于操作符<=
的行为。__gt__(self, other)
:定义大于操作符>
的行为。__ge__(self, other)
:定义大于等于操作符>=
的行为。
3. 算术操作
__add__(self, other)
:定义加法操作符+
的行为。__sub__(self, other)
:定义减法操作符-
的行为。__mul__(self, other)
:定义乘法操作符*
的行为。__truediv__(self, other)
:定义真除法操作符/
的行为。__floordiv__(self, other)
:定义地板除法操作符//
的行为。__mod__(self, other)
:定义取模操作符%
的行为。__pow__(self, other)
:定义幂操作符**
的行为。
4. 反向算术操作
__radd__(self, other)
:定义反向加法操作符+
的行为。__rsub__(self, other)
:定义反向减法操作符-
的行为。__rmul__(self, other)
:定义反向乘法操作符*
的行为。__rtruediv__(self, other)
:定义反向真除法操作符/
的行为。__rfloordiv__(self, other)
:定义反向地板除法操作符//
的行为。__rmod__(self, other)
:定义反向取模操作符%
的行为。__rpow__(self, other)
:定义反向幂操作符**
的行为。
5. 增量算术操作
__iadd__(self, other)
:定义增量加法操作符+=
的行为。__isub__(self, other)
:定义增量减法操作符-=
的行为。__imul__(self, other)
:定义增量乘法操作符*=
的行为。__itruediv__(self, other)
:定义增量真除法操作符/=
的行为。__ifloordiv__(self, other)
:定义增量地板除法操作符//=
的行为。__imod__(self, other)
:定义增量取模操作符%=
的行为。__ipow__(self, other)
:定义增量幂操作符**=
的行为。
6. 位运算操作
__and__(self, other)
:定义按位与操作符&
的行为。__or__(self, other)
:定义按位或操作符|
的行为。__xor__(self, other)
:定义按位异或操作符^
的行为。__lshift__(self, other)
:定义左移操作符<<
的行为。__rshift__(self, other)
:定义右移操作符>>
的行为。
7. 反向位运算操作
__rand__(self, other)
:定义反向按位与操作符&
的行为。__ror__(self, other)
:定义反向按位或操作符|
的行为。__rxor__(self, other)
:定义反向按位异或操作符^
的行为。__rlshift__(self, other)
:定义反向左移操作符<<
的行为。__rrshift__(self, other)
:定义反向右移操作符>>
的行为。
8. 增量位运算操作
__iand__(self, other)
:定义增量按位与操作符&=
的行为。__ior__(self, other)
:定义增量按位或操作符|=
的行为。__ixor__(self, other)
:定义增量按位异或操作符^=
的行为。__ilshift__(self, other)
:定义增量左移操作符<<=
的行为。__irshift__(self, other)
:定义增量右移操作符>>=
的行为。
9. 类型转换
__int__(self)
:定义将对象转换为整型的行为。__float__(self)
:定义将对象转换为浮点型的行为。__complex__(self)
:定义将对象转换为复数的行为。__bool__(self)
:定义将对象转换为布尔值的行为。__bytes__(self)
:定义将对象转换为字节的行为。
10. 容器相关
__len__(self)
:定义返回容器长度的方法。__getitem__(self, key)
:定义获取容器中某个元素的方法。__setitem__(self, key, value)
:定义设置容器中某个元素的方法。__delitem__(self, key)
:定义删除容器中某个元素的方法。__iter__(self)
:定义返回一个迭代器的方法。__next__(self)
:定义返回下一个元素的方法。
11. 上下文管理
__enter__(self)
:定义进入上下文的方法。__exit__(self, exc_type, exc_value, traceback)
:定义退出上下文的方法。
12. 其他
__call__(self, ...)
:定义对象可调用的方法。__contains__(self, item)
:定义检查容器中是否包含某个元素的方法。__hash__(self)
:定义返回对象的哈希值的方法。__format__(self, format_spec)
:定义对象的格式化方法。__sizeof__(self)
:定义返回对象占用内存大小的方法。
以上是 Python 中常见的魔术方法。每个魔术方法都有特定的用途,能够帮助我们在开发过程中实现更灵活和强大的功能。
代码示例
1. 初始化与表示
class Person:
def __init__(self, name, age):
self.name = name
self.age = age # 初始化对象属性
def __repr__(self):
return f'Person(name={self.name}, age={self.age})' # 返回对象的官方字符串表示
def __str__(self):
return f'{self.name} is {self.age} years old' # 返回对象的用户友好字符串表示
p = Person('Alice', 30)
print(repr(p)) # 输出: Person(name=Alice, age=30)
print(str(p)) # 输出: Alice is 30 years old
2. 比较操作
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.age == other.age # 比较年龄是否相等
def __lt__(self, other):
return self.age < other.age # 比较年龄是否小于
p1 = Person('Alice', 30)
p2 = Person('Bob', 25)
print(p1 == p2) # 输出: False
print(p1 < p2) # 输出: False
3. 算术操作
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 __sub__(self, other):
return Vector(self.x - other.x, self.y - other.y) # 定义向量相减
def __str__(self):
return f'({self.x}, {self.y})'
v1 = Vector(2, 3)
v2 = Vector(5, 7)
print(v1 + v2) # 输出: (7, 10)
print(v1 - v2) # 输出: (-3, -4)
4. 反向算术操作
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __radd__(self, other):
return Vector(self.x + other.x, self.y + other.y) # 反向相加
def __str__(self):
return f'({self.x}, {self.y})'
v1 = Vector(2, 3)
v2 = Vector(5, 7)
print(v2 + v1) # 输出: (7, 10)
5. 增量算术操作
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __iadd__(self, other):
self.x += other.x
self.y += other.y
return self # 增量相加
def __str__(self):
return f'({self.x}, {self.y})'
v1 = Vector(2, 3)
v2 = Vector(5, 7)
v1 += v2
print(v1) # 输出: (7, 10)
6. 位运算操作
class BinaryNumber:
def __init__(self, value):
self.value = value
def __and__(self, other):
return BinaryNumber(self.value & other.value) # 按位与操作
def __str__(self):
return bin(self.value)
b1 = BinaryNumber(0b1010)
b2 = BinaryNumber(0b1100)
print(b1 & b2) # 输出: 0b1000
7. 反向位运算操作
class BinaryNumber:
def __init__(self, value):
self.value = value
def __rand__(self, other):
return BinaryNumber(other.value & self.value) # 反向按位与操作
def __str__(self):
return bin(self.value)
b1 = BinaryNumber(0b1010)
b2 = BinaryNumber(0b1100)
print(b2 & b1) # 输出: 0b1000
8. 增量位运算操作
class BinaryNumber:
def __init__(self, value):
self.value = value
def __iand__(self, other):
self.value &= other.value
return self # 增量按位与操作
def __str__(self):
return bin(self.value)
b1 = BinaryNumber(0b1010)
b2 = BinaryNumber(0b1100)
b1 &= b2
print(b1) # 输出: 0b1000
9. 类型转换
class MyNumber:
def __init__(self, value):
self.value = value
def __int__(self):
return int(self.value) # 转换为整数
def __float__(self):
return float(self.value) # 转换为浮点数
n = MyNumber(5.5)
print(int(n)) # 输出: 5
print(float(n)) # 输出: 5.5
10. 容器相关
class MyList:
def __init__(self):
self.items = []
def __len__(self):
return len(self.items) # 返回容器长度
def __getitem__(self, index):
return self.items[index] # 获取容器中某个元素
def __setitem__(self, index, value):
self.items[index] = value # 设置容器中某个元素
def __delitem__(self, index):
del self.items[index] # 删除容器中某个元素
def __iter__(self):
return iter(self.items) # 返回迭代器
my_list = MyList()
my_list.items = [1, 2, 3, 4]
print(len(my_list)) # 输出: 4
print(my_list[2]) # 输出: 3
my_list[2] = 10
print(my_list[2]) # 输出: 10
del my_list[2]
print(list(my_list)) # 输出: [1, 2, 4]
11. 上下文管理
class MyContext:
def __enter__(self):
print('Entering context')
return self # 进入上下文
def __exit__(self, exc_type, exc_value, traceback):
print('Exiting context') # 退出上下文
with MyContext() as context:
print('Inside context')
# 输出:
# Entering context
# Inside context
# Exiting context
12. 其他
class CallableObject:
def __call__(self, *args, **kwargs):
print('Called with', args, kwargs) # 对象可调用
c = CallableObject()
c(1, 2, 3, key='value') # 输出: Called with (1, 2, 3) {'key': 'value'}