香港云主机最佳企业级服务商!

ADSL拨号VPS包含了中国大陆(联通,移动,电信,)

中国香港,国外拨号VPS。

当前位置:云主机 > python >

电信ADSL拨号VPS
联通ADSL拨号VPS
移动ADSL拨号VPS

python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享


时间:2021-04-29 10:47 作者:admin


分享一下刚遇到的一个小问题,我有一段类似于这样的python/' target='_blank'>python代码:
复制代码 代码如下:
# coding: utf-8

class A(object):

@property
def _value(self):
# raise AttributeError("test")
return {"v": "This is a test."}

def __getattr__(self, key):
print "__getattr__:", key
return self._value[key]

if __name__ == '__main__':
a = A()
print a.v

运行后可以得到正确的结果
复制代码 代码如下:
__getattr__: v
This is a test.
但是注意,如果把
复制代码 代码如下:
# raise AttributeError("test")


这行的注释去掉的话,即在_value方法里面抛出AttributeError异常,事情就会变得有些奇怪。程序运行的时候并不会抛出异常,而是会进入一个无限递归:
复制代码 代码如下:
File "attr_test.py", line 12, in __getattr__
return self._value[key]
File "attr_test.py", line 12, in __getattr__
return self._value[key]
RuntimeError: maximum recursion depth exceeded while calling a Python object

通过多方查找后发现是property装饰器的问题,property实际上是一个descriptor。在python doc中可以发现这样的文字:
复制代码 代码如下:
object.__get__(self, instance, owner)

Called to get the attribute of the owner class (class attribute access) or of an instance of that class (instance attribute access). owner is always the owner class, while instance is the instance that the attribute was accessed through, or None when the attribute is accessed through the owner. This method should return the (computed) attribute value or raise an AttributeError exception.

这样当用户访问._value时,抛出了AttributeError从而调用了__getattr__方法去尝试获取。这样程序就变成了无限递归。

这个问题看上去不复杂,但是当你的_value方法是比较隐晦的抛出AttributeError的话,调试起来就会比较困难了。

(责任编辑:admin)






帮助中心
会员注册
找回密码
新闻中心
快捷通道
域名登录面板
虚机登录面板
云主机登录面板
关于我们
关于我们
联系我们
联系方式

售前咨询:17830004266(重庆移动)

企业QQ:383546523

《中华人民共和国工业和信息化部》 编号:ICP备00012341号

Copyright © 2002 -2018 香港云主机 版权所有
声明:香港云主机品牌标志、品牌吉祥物均已注册商标,版权所有,窃用必究

云官方微信

在线客服

  • 企业QQ: 点击这里给我发消息
  • 技术支持:383546523

  • 公司总台电话:17830004266(重庆移动)
  • 售前咨询热线:17830004266(重庆移动)