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

 更新时间:2014年07月09日 09:53:56   投稿:junjie   我要评论
这篇文章主要介绍了python的描述符(descriptor)、装饰器(property)造成的一个无限递归问题分享,一个不太会遇到的问题,需要的朋友可以参考下

分享一下刚遇到的一个小问题,我有一段类似于这样的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的话,调试起来就会比较困难了。

相关文章

  • Python 使用指定的网卡发送HTTP请求的实例

    Python 使用指定的网卡发送HTTP请求的实例

    今天小编就为大家分享一篇Python 使用指定的网卡发送HTTP请求的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-08-08
  • Python实现的简单dns查询功能示例

    Python实现的简单dns查询功能示例

    这篇文章主要介绍了Python实现的简单dns查询功能,结合实例形式分析了Python基于socket模块的dns信息查询实现技巧,需要的朋友可以参考下
    2017-05-05
  • Python多继承顺序实例分析

    Python多继承顺序实例分析

    这篇文章主要介绍了Python多继承顺序,结合实例形式分析了Python多继承情况下继承顺序对同名函数覆盖的影响,需要的朋友可以参考下
    2018-05-05
  • 对Python3之进程池与回调函数的实例详解

    对Python3之进程池与回调函数的实例详解

    今天小编就为大家分享一篇对Python3之进程池与回调函数的实例详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Python 函数基础知识汇总

    Python 函数基础知识汇总

    Python中的函数,无论是命名函数,还是匿名函数,都是语句和表达式的集合。函数可以作为参数传递给其他函数,这些以其他函数作为参数的函数通常称为更高阶函数,这就构成了函数式编程中一个非常重要的部分。
    2018-03-03
  • Python3中的最大整数和最大浮点数实例

    Python3中的最大整数和最大浮点数实例

    今天小编就为大家分享一篇Python3中的最大整数和最大浮点数实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • 解决python写入带有中文的字符到文件错误的问题

    解决python写入带有中文的字符到文件错误的问题

    今天小编就为大家分享一篇解决python写入带有中文的字符到文件错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • 对python 操作solr索引数据的实例详解

    对python 操作solr索引数据的实例详解

    今天小编就为大家分享一篇对python 操作solr索引数据的实例详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-12-12
  • Python3.5集合及其常见运算实例详解

    Python3.5集合及其常见运算实例详解

    这篇文章主要介绍了Python3.5集合及其常见运算,结合实例形式分析了Python3.5集合的定义、功能、交集、并集、差集等常见操作技巧与相关注意事项,需要的朋友可以参考下
    2019-05-05
  • python通过实例讲解反射机制

    python通过实例讲解反射机制

    这篇文章主要介绍了python通过实例讲解反射机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10

最新评论