在构建类中使用数据描述符时,我在类上遇到了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
函数如何在类对象上起作用?
答案 0 :(得分:1)
getattr(A, 'a')
触发描述符协议,即使是在类上,也会调用String.__get__(None, A)
。
返回None
,因为您的String.__get__()
方法没有明确的return
语句。
对于课程,机制位于
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
。