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

作者:junjie 时间:2023-04-29 08:57:32 

分享一下刚遇到的一个小问题,我有一段类似于这样的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,描述符,descriptor,装饰器,property,无限递归
0
投稿

猜你喜欢

  • Python中创建对象列表的实现示例

    2023-08-15 07:20:35
  • Python办公自动化之Excel介绍

    2021-04-19 11:06:07
  • 快速掌握怎样选择准备安装的 MySQL版本

    2008-12-17 16:42:00
  • MySQL 数据库范式化设计理论总结

    2024-01-12 17:29:07
  • SHA256算法 asp源码

    2009-08-28 13:01:00
  • asp之自动闭合HTML/ubb标签函数+简单注释

    2008-09-29 12:21:00
  • 详解Golang中Context的原理和使用技巧

    2024-05-22 10:30:05
  • Python+Opencv识别两张相似图片

    2022-11-07 09:12:55
  • Python functools模块学习总结

    2023-09-22 07:21:54
  • python同时给两个收件人发送邮件的方法

    2021-10-23 07:31:36
  • 在Pycharm中设置默认自动换行的方法

    2022-09-10 04:29:00
  • 好用的VSCode头部注释插件Fileheader Pro

    2023-07-05 06:16:00
  • windows server2016安装MySQL5.7.19解压缩版教程详解

    2024-01-22 01:16:29
  • mysql 超大数据/表管理技巧

    2024-01-16 22:14:05
  • 把vgg-face.mat权重迁移到pytorch模型示例

    2021-11-03 16:29:20
  • 利用Python的pandas数据处理包将宽表变成窄表

    2021-07-28 20:00:11
  • GoLang切片并发安全解决方案详解

    2024-05-09 09:54:15
  • 详细介绍Ruby中的正则表达式

    2023-12-03 19:44:46
  • 解决python selenium3启动不了firefox的问题

    2022-12-02 11:36:34
  • VBScript中的eval()函数

    2008-04-09 13:41:00
  • asp之家 网络编程 m.aspxhome.com