Skip to main content

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 内置类型,提高代码的可读性和可维护性! 🚀