python中的魔法方法是一些可以让你对类添加“魔法”的特殊方法,它们经常是两个下划线包围来命名的
Python的魔法方法,也称为dunder(双下划线)方法。大多数的时候,我们将它们用于简单的事情,例如构造函数(__init__)、字符串表示(__str__, __repr__)或算术运算符(__add__/__mul__)。其实还有许多你可能没有听说过的但是却很好用的方法,在这篇文章中,我们将整理这些魔法方法!
迭代器的大小
我们都知道__len__方法,可以用它在容器类上实现len()函数。但是,如果您想获取实现迭代器的类对象的长度怎么办?
it = iter(range(100)) print(it.__length_hint__()) # 100 next(it) print(it.__length_hint__()) # 99 a = [1, 2, 3, 4, 5] it = iter(a) print(it.__length_hint__()) # 5 next(it) print(it.__length_hint__()) # 4 a.append(6) print(it.__length_hint__()) # 5
你所需要做的就是实现__length_hint__方法,这个方法是迭代器上的内置方法(不是生成器),正如你上面看到的那样,并且还支持动态长度更改。但是,正如他的名字那样,这只是一个提示(hint),并不能保证完全准确:对于列表迭代器,可以得到准确的结果,但是对于其他迭代器则不确定。但是即使它不准确,它也可以帮我们获得需要的信息,正如PEP 424中解释的那样
length_hint must return an integer (else a TypeError is raised) or NotImplemented, and is not required to be accurate. It may return a value that is either larger or smaller than the actual size of the container. A return value of NotImplemented indicates that there is no finite length estimate. It may not return a negative value (else a ValueError is raised).
元编程
大部分很少看到的神奇方法都与元编程有关,虽然元编程可能不是我们每天都需要使用的东西,但有一些方便的技巧可以使用它。
一个这样的技巧是使用__init_subclass__作为扩展基类功能的快捷方式,而不必处理元类:
class Pet: def __init_subclass__(cls, /, default_breed, **kwargs):