在具有数据描述符的类上使用getattr

时间:2016-10-05 15:03:13

标签: python python-2.7 class getattr

在构建类中使用数据描述符时,我在类上遇到了getattr函数的奇怪行为。

# this is a data descriptor
class String(object):
    def __get__(self, instance, owner):
        pass
    def __set__(self, instance, value):
        pass

# This defines a class A with 'dot' notation support for attribute 'a'
class A(object):
    a = String()

obj = A()
assert getattr(A, 'a') is A.__dict__['a']
# This raises AssertionError

LHS返回一个空字符串,而RHS返回String的实例。我认为对象上的getattr是获取__dict__内密钥的值。 getattr函数如何在类对象上起作用?

2 个答案:

答案 0 :(得分:1)

getattr(A, 'a')触发描述符协议,即使是在类上,也会调用String.__get__(None, A)

返回None,因为您的String.__get__()方法没有明确的return语句。

来自Descriptor Howto

  

对于课程,机制位于type.__getattribute__(),将B.x转换为B.__dict__['x'].__get__(None, B)

getattr(A, 'a')只是来自A.a的动态,因此执行了A.__dict__['x'].__get__(None, A),这就是为什么你不能与A.__dict__['x']获得相同的东西。

如果您希望它返回描述符对象本身,则必须显式;在这种情况下,instance将设置为None

class String(object):
    def __get__(self, instance, owner):
        if instance is None:
            return self
    def __set__(self, instance, value):
        pass

这是property描述符对象的作用。

请注意owner的{​​{1}}参数是可选的;如果没有设置,你应该使用descriptor.__get__代替。

答案 1 :(得分:0)

getattr(A, 'a')A.a相同。如果存在,则调用相应的描述符。因此它提供了描述符所呈现的值,即None