鱼C论坛

 找回密码
 立即注册
查看: 1654|回复: 4

[已解决]关于魔法方法中无限递归的问题

[复制链接]
发表于 2020-2-23 00:02:35 | 显示全部楼层 |阅读模式

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

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

x
__len__(self)定义当被 len() 调用时的行为(返回容器中元素的个数),但是在下面代码中__len__的改写那一块,返回的是len(self.values),那Python检测到len()被调用,不是应该又自动调用__len__()魔法方法,然后形成一个死递归吗?
  1. class CountList:
  2.         def __init__(self,*args):
  3.                 self.values = [x for x in args]
  4.                 self.count = {}.fromkeys(range(len(self.values)),0)
  5.         def __len__(self):
  6.                 return len(self.values)
  7.         def __getitem__(self,key):
  8.                 self.count[key] += 1
  9.                 return self.values[key]
复制代码


就比如下面这个例子会在进行加法和减法运算的时候陷入死递归一样:
  1. class New_int(int):
  2.     def __add__(self,other):
  3.         return self + other
  4.     def __sub__(self,other):
  5.         return self - other
复制代码
最佳答案
2020-2-23 00:30:39
  1. return len(self.values)
复制代码

这一行中的 len() 函数 是 python 的内置的 len() 函数, 因为里面的参数值是 self.values,如果是参数值是 self 的话就会是你说的无限递归了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-23 00:30:39 | 显示全部楼层    本楼为最佳答案   

回帖奖励 +10 鱼币

  1. return len(self.values)
复制代码

这一行中的 len() 函数 是 python 的内置的 len() 函数, 因为里面的参数值是 self.values,如果是参数值是 self 的话就会是你说的无限递归了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2020-2-23 10:03:02 | 显示全部楼层
°蓝鲤歌蓝 发表于 2020-2-23 00:30
这一行中的 len() 函数 是 python 的内置的 len() 函数, 因为里面的参数值是 self.values,如果是参数值 ...

我想再问一个问题,可能显得有点多余
是不是有的魔法方法只有通过自行改写才能实现一定的功能,否则就什么都做不了。例如__len__,不改写也不会在调用len()的时候返回长度;
而有的则本来就可以自动调用并且有功能,例如__new__(),即便不改写,创建实例对象时__new__也会被调用并且返回实例对象
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-2-23 11:56:45 | 显示全部楼层
Moho 发表于 2020-2-23 10:03
我想再问一个问题,可能显得有点多余
是不是有的魔法方法只有通过自行改写才能实现一定的功能,否则就什 ...

不是改写,而是实现。
改写是对原有的方法进行改变,而实现则是原来没有,现在创建。
上面的 __len__() 方法不是每个类都有的,只有实现了 __len__() 方法的类才可以 通过 len()  方法返回其长度。
因为所有的类的父类都是 object, 而 object实现了__new__() 方法,所以这个方法是每个类都有的,无须你再次实现,如果你想做些改变,则可以改写它。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-2-23 18:08:09 | 显示全部楼层
°蓝鲤歌蓝 发表于 2020-2-23 11:56
不是改写,而是实现。
改写是对原有的方法进行改变,而实现则是原来没有,现在创建。
上面的 __len__() ...

嗯嗯,感谢大神的解答
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-18 21:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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