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的话,调试起来就会比较困难了。


猜你喜欢
- 本文介绍基于PowerShell语言,对文件夹中全部文件的名称加以批量替换、修改的方法。在之前的文章基于Python实现自动批量修改文件名称
- 本文实例为大家分享了JS实现长图上下滚动的具体代码,供大家参考,具体内容如下案例描述将一张长图放在某一固定长宽的盒子里,当鼠标置于盒子的上半
- 所有的缓存数据都存储在服务器的内存中,因此重启服务器会导致数据丢失,基于HTTP通信会将使开发变得简单,但性能不会太好缓存服务接口本程序采用
- windows系统中文件名不能包含 \ / : * ? " < > |想要创建必须过滤掉这些字符def setFile
- 实例一--爬取页面import requestsurl="https//itemjd.com/2646846.html"
- 📚引言泰坦尼克号的沉没是历史上最惨痛的沉船事件之一。1912年4月15日,泰坦尼克号在其处女航中与冰山相撞后沉没,2224名乘客和船员中的1
- 本文实例讲述了PHP中使用addslashes函数转义的安全性原理分析。分享给大家供大家参考。具体分析如下:先来看一下ECshop中adds
- 1.简介celery(芹菜)是一个异步任务队列/基于分布式消息传递的作业队列。它侧重于实时操作,但对调度支持也很好。celery用于生产系统
- 一.执行代码yum install xz-devel yum install python-backports-lzmapip3 insta
- 一. 使用logging模块时用python写代码时,logging模块最基本的几行配置,如下:import logginglogging.
- 关于PHP调用Python数据传输问题这是以前大学时做项目出现的问题,现在把它挪上来,希望给遇到问题的未来大佬给出一些小的思路,请大佬们不要
- 在上篇博客中,提到了对一个脚本进行的多次优化。当时以为已经优化得差不多了,但是当测试人员测试时,我才发现,踩到了Python的一个大坑。在上
- 一、watch使用的几种方法1、 通过 watch 监听 msg 数据的变化。watch: { msg(oldVa
- 1.第一个实例:HelloWorld1.编写python代码from flask import Flaskapp=Flask(__name_
- 我们经常会遇到这样的问题你还在为你的MySQL命令模式下,前面的提示信息还是:mysql>,那么我们如何更改mysql命令下提示信息呢
- 本文实例讲述了MySQL关于字符串中数字排序的问题。分享给大家供大家参考,具体如下:MySQL字符串相信大家都不陌生,在MySQL字符串排序
- Pycharm作为一款强力的Python IDE,在使用过程中感觉一直找不到全面完整的参考手册,因此决定对官网的Pycharm教程进行简要翻
- 很多人错误地认为ASP是简单、低效的代名词,认为ASP是低能的,不足挂齿的,也很简单,一学就会,一琢磨就精通。有人讲ASP不安全,写ASP的
- argparse是python用于解析命令行参数和选项的标准模块。很多时候,需要用到解析命令行参数的程序,目的是在终端窗口输入训练的参数和选
- 前端时间智能信息处理实训,我选择的课题为身份证号码识别,对中华人民共和国公民身份证进行识别,提取并识别其中的身份证号码,将身份证号码识别为字