Python 面向对象中的常用魔术方法(Magic Methods)
魔术方法(Magic Methods) 也叫 特殊方法(Dunder Methods,双下划线方法),是 Python 类中自带的特殊命名方法,通常以 __xxx__
形式命名,如 __init__
、__str__
等。这些方法可以让对象更具可读性、可操作性,并且支持运算符重载。
1.对象创建与销毁
方法 | 作用 |
---|---|
__init__(self, ...) | 构造函数,创建对象时自动调用 |
__new__(cls, ...) | 创建对象实例(用于控制实例化过程) |
__del__(self) | 析构函数,删除对象时自动调用 |
示例:
class Person:
def __new__(cls, *args, **kwargs):
print("调用 __new__ 方法")
return super().__new__(cls) # 返回实例对象
def __init__(self, name):
print("调用 __init__ 方法")
self.name = name
def __del__(self):
print(f"对象 {self.name} 被销毁")
p = Person("Alice") # 调用 __new__ 和 __init__
del p # 触发 __del__
输出:
调用 __new__ 方法
调用 __init__ 方法
对象 Alice 被销毁
2.对象字符串表示
方法 | 作用 |
---|---|
__str__(self) | print(obj) 或 str(obj) 时调用,提供 用户友好 的字符串表示 |
__repr__(self) | repr(obj) 或交互式环境调用,提供 开发者友好的 字符串表示 |
示例:
class Car:
def __init__(self, brand, model):
self.brand = brand
self.model = model
def __str__(self):
return f"{self.brand} - {self.model}"
def __repr__(self):
return f"Car(brand='{self.brand}', model='{self.model}')"
car = Car("Tesla", "Model 3")
print(str(car)) # 调用 __str__
print(repr(car)) # 调用 __repr__
输出:
Tesla - Model 3
Car(brand='Tesla', model='Model 3')
3.算数运算符重载
方法 | 作用 |
---|---|
__add__(self, other) | + 运算符(加法) |
__sub__(self, other) | - 运算符(剑法) |
__mul__(self, other) | * 运算符(乘法) |
__truediv__(self, other) | / 运算符(除法) |
__floordiv__(self, other) | // 运算符(整除) |
__mod__(self, other) | % 运算符(取模) |
__pow__(self, other) | ** 运算符(幂运算) |
示例:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __str__(self):
return f"({self.x}, {self.y})"
p1 = Point(1, 2)
p2 = Point(3, 4)
print(p1 + p2) # 调用 __add__,输出:(4, 6)
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 __lt__(self, other):
return self.age < other.age
p1 = Person("张三", 20)
p2 = Person("李四", 18)
print(p1 < p2)
# 两种写法是等价的
print(p1.__lt__(p2))
输出:
False
False
5.索引与切片
方法 | 作用 |
---|---|
__getitem__(self, index) | 获取索引元素 obj[index] |
__setitem__(self, index, value) | 设置索引元素 obj[index] = value |
__delitem__(self, index) | 删除索引元素 del obj[index] |
示例:
class CustomList:
def __init__(self, items):
self.items = 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]
nums = CustomList([1, 2, 3, 4])
print(nums[1]) # 调用 __getitem__,输出: 2
nums[1] = 99 # 调用 __setitem__
del nums[2] # 调用 __delitem__
print(nums.items) # 输出: [1, 99, 4]
6.迭代器协议
方法 | 作用 |
---|---|
__iter__(self) | 返回迭代器对象 |
__next__(self) | 返回下一个元素 |
示例:
class MyRange:
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
val = self.current
self.current += 1
return val
nums = MyRange(1, 5)
for num in nums:
print(num) # 输出: 1 2 3 4
7.上下文管理器
方法 | 作用 |
---|---|
__enter__(self) | 进入 with 语句块时调用 |
__exit__(self, exc_type, exc_value, traceback) | 退出 with 语句块时调用 |
示例:
class FileManager:
def __init__(self, filename):
self.file = open(filename, "w")
def __enter__(self):
return self.file
def __exit__(self, exc_type, exc_value, traceback):
self.file.close()
with FileManager("test.txt") as f:
f.write("Hello, World!")
8.查看魔术方法
class A:
pass
print(dir(A)) # 查看类的所有属性和方法
输出:
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
__doc__
:表示类的描述信息
__module__
:表示当前操作的对象在哪个模块(结合:if __name__ == '__main__':
的理解)
class A:
"""表示类的描述信息"""
def func(self):
pass
pass
print(A.__doc__) # 打印类的注释信息,输出:表示类的描述信息
print(A.__module__) # 表示当前操作的对象再哪个模块,输出:__main__
总结
Python 提供了丰富的魔术方法,使对象更强大、易用。常见的有:
- 对象创建销毁:
__init__
、__del__
- 字符串表示:
__str__
、__repr__
- 运算符重载:
__add__
、__sub__
、__eq__
、__lt_
- 索引与迭代:
__getitem__
、__iter__
- 上下文管理:
__enter__
、__exit__
这些魔术方法能让类更像 Python 内置类型,提高代码的可读性和可维护性! 🚀