鱼C论坛

 找回密码
 立即注册
查看: 1838|回复: 0

[学习笔记] 类和对象-魔法方法-上

[复制链接]
发表于 2023-3-31 22:31:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
>>> #魔法方法__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([1, 2, 3, 4, 5])
>>> print(3 in c)
Hello
True
>>> #[1, 2, 3, 4, 5]对应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]
...                 self.i += 1
...                 return item  
...
>>> c = C([1, 2, 3, 4, 5])
>>> 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[item]
...
>>> c = C([1, 2, 3, 4, 5])
>>> print(3 in c)
getitem->getitem->getitem->True
>>> print(6 in c)
getitem->getitem->getitem->getitem->getitem->getitem->False
>>>

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
歌者文明清理员 + 5 + 5 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-24 01:14

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表