繁体   English   中英

将类描述符与get和set一起使用时,超过了最大递归深度

[英]maximum recursion depth exceeded when using a class descriptor with get and set

我一直在玩我的代码,最终得到了以下结果:

class TestProperty:
    def __init__(self,func):
         self.func = func
    def __set__(self,instance,value):
        setattr(instance,self.func.__name__,value)
    def __get__(self,instance,cls):
        if instance is None:
            return self
        else:
            return getattr(instance,self.func.__name__)


class John(object):
    def __init__(self):
        pass

    @TestProperty
    def TestProp(self):
       print('This line won\'t be printed')

p = John()
p.TestProp = 99
print(p.TestProp)

我试图了解在创建类描述符并将其用于方法而不是属性时的行为。 我很难理解下面发生了什么,如果有人可以向我阐明一下这真是太好了,这怎么会成为递归错误?

我最初的猜测是这样的:

  1. 用描述符修饰的方法称为
  2. 根据我们访问它的方式调用__set____get__
  3. 描述符尝试设置调用实例的值,该实例最终将其映射回步骤1(错误)。

谁能向我详细解释这是怎么发生的以及我该如何解决?

提供的代码除了了解类描述符的行为外没有其他用途。

不要使用getattr()setattr() ; 您正在那里再次触发描述符! 描述符使用setattr()getattr()处理所有对TestProp名称的访问,就像通过p.TestProp一样。

直接在instance.__dict__设置属性值。

def __get__(self,instance,cls):
    if instance is None:
        return self
    try:
        return instance.__dict__[self.func.__name__]
    except KeyError:
        raise AttributeError(self.func.__name__)
def __set__(self,instance,value):
    instance.__dict__[self.func.__name__] = value

之所以有效,是因为您有一个数据描述符 ; 数据描述符优先于实例属性。 即使实例__dict__存在名称'TestProp'p.TestProp访问p.TestProp继续使用该类上的描述符对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM