get_dict_attr@H_403_2@(下图)
attr@H_403_2@在给定对象的中查找
__dict__@H_403_2@,如果存在则返回关联的值。如果
attr@H_403_2@不是其中的关键,则搜索
__dict__@H_403_2@对象的MRO
__dict__@H_403_2@。如果找不到密钥,
AttributeError@H_403_2@则引发。
def get_dict_attr(obj, attr):
for obj in [obj] + obj.__class__.mro():
if attr in obj.__dict__:
return obj.__dict__[attr]
raise AttributeError
@H_403_2@
例如,
class Foo(object):
x=1
def bar(self):
pass
@property
def baz(self):
return 0
foo=Foo()
print(get_dict_attr(foo,'x'))
# 1
print(get_dict_attr(foo,'bar'))
# <unbound method Foo.bar>
print(get_dict_attr(foo,'baz'))
# <property object at 0xb77c0dc4>
print(get_dict_attr(foo,'y'))
# AttributeError
@H_403_2@
请注意,这与属性查找的常规规则有很大不同。一方面,中的数据描述符obj.__class__.__dict__@H_403_2@(带有
__get__@H_403_2@和
__set__@H_403_2@方法的描述符)通常优先于中的值
obj.__dict__@H_403_2@。在中
get_dict_attr@H_403_2@,
obj.__dict__@H_403_2@具有优先权。
get_dict_attr@H_403_2@不尝试致电
__getattr__@H_403_2@。
最后,get_dict_attr@H_403_2@仅适用于
obj@H_403_2@作为新样式类实例的对象。
不过,我希望这会有所帮助。
class Foo(object):
@property
def bar(self):
return 0
f = Foo()
@H_403_2@
print(Foo.bar)
# <property object at 0xb76d1d9c>
@H_403_2@
您看到的bar@H_403_2@是关键
Foo.__dict__@H_403_2@:
print(Foo.__dict__['bar'])
# <property object at 0xb775dbbc>
@H_403_2@
所有属性都是描述符,这意味着它具有__get__@H_403_2@方法:
print(Foo.bar.__get__)
# <method-wrapper '__get__' of property object at 0xb76d7d74>
@H_403_2@
您可以通过传递objectf@H_403_2@和
f@H_403_2@as的类来调用方法:
print(Foo.bar.__get__(f,Foo))
# 0
@H_403_2@
在这种情况下:
Foo B
| Foo.__dict__={'bar':b} | B.__dict__={'__get__':...}
| \ |
f `--------> b
@H_403_2@
f.bar@H_403_2@使
b.__get__(f,Foo)@H_403_2@被调用。
这将在此处详细说明。