类和对象-魔法方法-上
>>> #魔法方法__contains__()用于实现成员关系的检测,当使用in和not in进行成员关系判断时便会触发该方法;魔法方法__bool__()则与布尔测试bool()相对应。
这节课主要讲的是魔法方法的代偿机制,所谓代偿,就是替代+补偿,指的是当本该发挥作用的魔法方法没有被定义时,Python便会退而求其次,寻找类似的相关方法来调用,如用
__getitem__()作为__iter__()和__next__()的代偿,
__iter__()和__next__()作为__contains__()的代偿,__len__()作为__bool__()的代偿等,
看起来有点奇怪,其实也算是一种“不得已而为之”的折衷方案吧……
比较运算相关的魔法方法包括:__lt__()(<)、__le__()(<=)、__gt__()(>)、__ge__()(>=)、__eq__()(==)、__ne__()(!=)。
通过重写这些魔法方法,可以实现对两个字符串长度而非编码值的快速比较。
最后,当我们不想让某个魔法方法生效时,只需将其赋值为None,此时若该魔法方法被触发,程序便会报错。通过这种手段,我们就可以阻止某些不希望的情形(如成员关系判断等)出现,抑制了Python可能引发误会的代偿机制,进而避免了难以调试的bug,真是未雨绸缪的好主意啊
>>> class C:
... def __init__(self, data):
... self.data = data
... def __contains__(self, item):
... print('Hello')
... return item in self.data
...
>>> c = C()
>>> print(3 in c)
Hello
True
>>> #对应self.data,3对应__contains__()魔法方法中的item
>>> #__contains__()代偿 P189 -> __iter__() + __next__() -> __getitem__()
>>> class C:
... def __init__(self, data):
... self.data = data
... def __iter__(self):
... print('iter', end='->')
... self.i = 0
... return self
... def __next__(self):
... print('next', end='->')
... if self.i == len(self.data):
... raise StopIteration
... item = self.data
... self.i += 1
... return item
...
>>> c = C()
>>> print(3 in c)
iter->next->next->next->True
>>> #首先调用iter将列表变为迭代器,再按个使用next拿出数据比较,直到找到的时候返回True
>>> print(6 in c)
iter->next->next->next->next->next->next->False
>>> print(5 in c)
iter->next->next->next->next->next->True
>>> class C:
... def __init__(self, data):
... self.data = data
... def __getitem__(self, item):# item对应的不是3 in c中的3,而是迭代时的0,1,2....
... print('getitem', end = '->')
... return self.data
...
>>> c = C()
>>> print(3 in c)
getitem->getitem->getitem->True
>>> print(6 in c)
getitem->getitem->getitem->getitem->getitem->getitem->False
>>>
页:
[1]