特殊方法的存在是为了被 Python
解释器调用的
首先明确一点,特殊方法的存在是为了被 Python 解释器调用的,你自己并不需要调用它们。也就是说没有 my_object.__len__()
这种写法,而应该使用 len(my_object)
。在执行 len(my_object)
的时候,如果 my_object
是一个自定义类的对象,那么 Python 会自己去调用其中由你实现的 __len__
方法。
然而如果是 Python 内置的类型,比如列表(list
)、字符串(str
)、字节序列(bytearray
)等,那么 CPython 会抄个近路,__len__
实际上会直接返回 PyVarObject
里的 ob_size
属性。PyVarObject
是表示内存中长度可变的内置对象的 C 语言结构体。直接读取这个值比调用一个方法要快很多。
很多时候,特殊方法的调用是隐式的,比如 for i in x:
这个语句,背后其实用的是 iter(x)
,而这个函数的背后则是 x.__iter__()
方法。当然前提是这个方法在 x 中被实现了。
通常你的代码无需直接使用特殊方法。除非有大量的元编程存在,直接调用特殊方法的频率应该远远低于你去实现它们的次数。唯一的例外可能是 __init__
方法,你的代码里可能经常会用到它,目的是在你自己的子类的 __init__
方法中调用超类的构造器。
通过内置的函数(例如 len、iter、str
,等等)来使用特殊方法是最好的选择。这些内置函数不仅会调用特殊方法,通常还提供额外的好处,而且对于内置的类来说,它们的速度更快。14.12 节中有详细的例子。
不要自己想当然地随意添加特殊方法,比如 __foo__
之类的,因为虽然现在这个名字没有被 Python 内部使用,以后就不一定了。