BrightXiong 发表于 2023-3-31 22:31:54

类和对象-魔法方法-上

>>> #魔法方法__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]
查看完整版本: 类和对象-魔法方法-上