为什么通过对象描述符创建的属性需要具有与其原始名称不同的值

问题描述 投票:0回答:1

我编写了这个描述符类,当我尝试在不同的类中使用它时,它给了我这个错误:

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__

返回的值不同吗
python descriptor
1个回答
0
投票

这是因为您正在打电话:

getattr(instance, self.internal_name)

由于

self.internal_name
与正在访问的描述符实例的名称具有相同的值,因此
getattr
会调用相同实例的同一描述符实例的
__get__
,从而导致无限递归。同样的情况也适用于您拨打
setattr

通过将

self.internal_name
命名为与描述符实例的名称不同,
getattr(instance, self.internal_name)
不再引用描述符实例的值,并且会正确回退到在实例的成员字典中查找属性名称以及在MRO。

© www.soinside.com 2019 - 2024. All rights reserved.