我编写了这个描述符类,当我try 在不同的类中使用它时,会出现以下错误: RecursionError: maximum recursion depth exceeded

class x:
    def __init__(...):
        ...

    def __set_name__(self, _, name):
        self.internal_name = name

    def __get__(self, instance, _):
        if instance is None:
            return
        else:
            return getattr(instance, self.internal_name)

    def __set__(self, instance, value):
        if instance is None:
            return
        else:
            setattr(instance, self.internal_name, value)

我发现,通过改变我的__set_name__方法,我不再得到这个问题:

def __set_name__(self, _, name):
    self.internal_name = f'_{name}'

但我不确定为什么会出现这种情况.您能解释一下为什么我需要确保名称与从__set_name__返回的值不同吗

推荐答案

这是因为你在呼叫:

getattr(instance, self.internal_name)

由于self.internal_name与被访问的描述符实例的名称具有相同的值,因此getattr调用具有相同实例的相同描述符实例的另一个调用__get__,该调用再次调用getattr(instance, self.internal_name),从而导致无限递归.同样的情况也适用于你拨打的setattr.

通过以与描述符实例的名称不同的方式命名self.internal_name,getattr(instance, self.internal_name)不再引用值的描述符实例,并且将适当地后退到查找实例的成员字典中的属性名称和MRO中的类型.

Python相关问答推荐

多处理代码在while循环中不工作

如何根据日期和时间将状态更新为已过期或活动?

DataFrame groupby函数从列返回数组而不是值

删除最后一个pip安装的包

如何避免Chained when/then分配中的Mypy不兼容类型警告?

如何在虚拟Python环境中运行Python程序?

基于字符串匹配条件合并两个帧

PyQt5,如何使每个对象的 colored颜色 不同?'

使用Python更新字典中的值

使用Python从URL下载Excel文件

Plotly Dash Creating Interactive Graph下拉列表

isinstance()在使用dill.dump和dill.load后,对列表中包含的对象失败

与命令行相比,相同的Python代码在Companyter Notebook中运行速度慢20倍

BeautifulSoup-Screper有时运行得很好,很健壮--但有时它失败了::可能这里需要一些更多的异常处理?

504未连接IB API TWS错误—即使API连接显示已接受''

如何在Python中自动创建数字文件夹和正在进行的文件夹?

pytest、xdist和共享生成的文件依赖项

设置索引值每隔17行左右更改的索引

PYTHON中的pd.wide_to_long比较慢

如何将一个文件的多列导入到Python中的同一数组中?