Python 中的魔术方法

91 阅读2分钟

什么是魔术方法

在 Python 中,魔术方法(Magic Methods) ,也叫特殊方法(Special Methods)dunder 方法(Double Underscore Methods) ,是指那些以双下划线开头和结尾的方法,例如 __init____str____call____len__ 等。

它们的“魔术”之处在于:你通常不会直接调用它们,而是由 Python 解释器在特定场景下自动调用,从而让你的对象能够支持内置操作(如打印、加法、迭代、调用等)

注意事项

  • 不要手动调用魔术方法(除非必要)
    • 应该写 len(obj) 而不是 obj.__len__(),因为前者有安全检查和回退机制。
  • 不是所有 __xxx__ 都是魔术方法
    • 比如 __private 是名称改写(name mangling),不属于魔术方法。
  • 魔术方法是 Python “鸭子类型” 和协议(Protocol)的基础
    • 只要你的类实现了 __iter__,它就可以被 for 循环使用,无需继承特定类。

常见的魔术方法

你写的代码实际调用的魔术方法作用说明
obj = MyClass()__new____init__创建并初始化对象
print(obj)__str__返回人类可读的字符串表示
repr(obj)__repr__返回开发者友好的字符串表示
len(obj)__len__支持 len() 函数
obj + other__add__重载 + 运算符
obj[key]__getitem__支持索引访问(如字典、列表)
for x in obj__iter__支持迭代
with obj: ...__enter____exit__支持上下文管理器(with语句)
obj()__call__让对象可被调用

什么魔方方法会被默认调用

操作 / 语法自动调用的魔法方法
a + ba.__add__(b)
len(obj)obj.__len__()
str(obj)obj.__str__()
repr(obj)obj.__repr__()
obj[key]obj.__getitem__(key)
obj()obj.__call__()
for x in objobj.__iter__()
with obj: ...obj.__enter__()obj.__exit__()
bool(obj) 或 if obj:obj.__bool__()(或回退到 __len__()
obj.attrobj.__getattribute__('attr')

举个__call__的例子

class Test:
    def __init__(self,print_args):
        self.print_args =print_args
    
    def __call__(self,print_args = True):
        print(self.print_args)


test1  =Test(True)

# 此时,调用的是 __str__ 函数
print(test1) 

# 调用的是 __call__ 函数
test1()