什么是魔术方法
所谓魔法方法,其官方名称为 special method,是 Python 的一种高级语法特性。它允许你在类中自定义函数,并将其绑定到类的特殊行为中。例如在类 A 中定义 __str__() 函数,调用 时会自动触发该方法。
本文详细介绍了 Python 中的魔术方法(Magic Methods),涵盖对象创建与初始化(__new__, __init__)、销毁(__del__)、字符串表示(__repr__, __str__)、格式化(__format__)、可调用对象(__call__)、比较运算、容器协议及迭代器协议等核心内容。通过代码示例展示了如何自定义类行为,包括单例模式实现、上下文管理器编写及运算符重载,帮助开发者深入理解 Python 的高级语法特性。

所谓魔法方法,其官方名称为 special method,是 Python 的一种高级语法特性。它允许你在类中自定义函数,并将其绑定到类的特殊行为中。例如在类 A 中定义 __str__() 函数,调用 时会自动触发该方法。
str(A())虽然 Magic Methods 这个名字在官方文档中不常见,但已被广泛使用。这些方法通常以双下划线开头和结尾,因此也被称为 dunder methods(double underscore)。
__new__ 和 __init__这两个方法控制对象的创建过程:
__new__:负责创建实例对象,是静态方法,返回实例。__init__:负责初始化实例,接收已创建的实例作为第一个参数。class A:
def __new__(cls, *args, **kwargs):
print("__new__")
return super().__new__(cls, *args, **kwargs)
def __init__(self):
print("__init__")
if __name__ == '__main__':
a = A()
输出顺序为 __new__ 后接 __init__。逻辑上可理解为:
obj = __new__(A)
__init__(obj)
何时使用 __new__?
主要用于单例模式、元类控制或不可变类型定制。以下是一个简单的单例实现:
class Singleton:
_instance = None
def __new__(cls):
if not cls._instance:
cls._instance = super().__new__(cls)
return cls._instance
s1 = Singleton()
s2 = Singleton()
print(s1 is s2) # True
__del____del__() 是析构方法,当对象引用计数归零时被调用。注意 del 关键字仅减少引用计数,不一定立即触发 __del__。建议优先使用上下文管理器 (with) 管理资源。
class MyClass:
def __del__(self):
print("对象被销毁")
__repr__ 和 __str____repr__:用于调试,应尽可能还原对象状态。__str__:用于用户展示,更友好。若未定义 __str__,则默认调用 __repr__。
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", 25)
print(str(p)) # Alice is 25 years old
print(repr(p)) # Person(name=Alice, age=25)
__format__用于自定义格式化输出,配合 f-string 或 format() 使用。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __format__(self, format_spec):
if format_spec == "r":
return f"({self.y}, {self.x})"
return f"({self.x}, {self.y})"
p = Point(1, 2)
print(f"{p:r}") # (2, 1)
__call__使实例像函数一样被调用。
class Adder:
def __init__(self, n):
self.n = n
def __call__(self, x):
return self.n + x
add_5 = Adder(5)
print(add_5(3)) # 8
通过重载比较方法实现自定义排序或判断。
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def __lt__(self, other):
return (self.x**2 + self.y**2) < (other.x**2 + other.y**2)
v1 = Vector(1, 2)
v2 = Vector(2, 1)
print(v1 == v2) # False
print(v1 < v2) # True
__len__, __getitem__, __setitem__让类支持 len(), [] 索引操作。
class MyList:
def __init__(self):
self.data = []
def __len__(self):
return len(self.data)
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, index, value):
self.data[index] = value
ml = MyList()
ml.append(10) # 需手动维护 data
__iter__ 和 __next__使对象可遍历。
class Counter:
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
for i in Counter(1, 3):
print(i) # 1, 2, 3
__enter__ 和 __exit__支持 with 语句,用于资源自动管理。
class FileManager:
def __init__(self, filename):
self.filename = filename
self.file = None
def __enter__(self):
self.file = open(self.filename, 'w')
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
if self.file:
self.file.close()
with FileManager('test.txt') as f:
f.write('Hello')
魔术方法是 Python 面向对象编程的核心机制之一。掌握它们可以极大地增强类的灵活性和表现力。从对象生命周期管理到运算符重载,再到自定义迭代和上下文管理,理解并合理使用这些方法能写出更 Pythonic 的代码。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online