从文档中。
对于物体来说,机器在object.__getattribute__()
其中转化b.x
为type(b).__dict__['x'].__get__(b, type(b))
。
也就是说,对实例( b
) 的属性查找转换为对类( type(b)
) 的描述符调用。描述符在类级别上运行。
至于为什么会这样,这是因为描述符基本上是一种在属性查找上进行类似方法的工作(即调用方法)的方法。方法本质上是类级别的行为:您通常在类上定义您想要的方法,并且您不会向单个实例添加额外的方法。在实例上进行描述符查找就像在实例上定义方法一样。
现在,可以为实例分配新方法,也可以让描述符作用于特定类的实例。你只需要做额外的工作。正如上面的文档引用所说,机器位于 中object.__getattribute__
,因此您可以通过在类上定义自定义来覆盖它__getattribute__
:
class Foo(object):
def __getattribute__(self, attr):
myDict = object.__getattribute__(self, '__dict__')
if attr in myDict and hasattr(myDict[attr], '__get__'):
return myDict[attr].__get__(self, type(self))
else:
return super(Foo, self).__getattribute__(attr)
class D(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
pass
def __get__(self, obj, objtype=None):
return 5
进而:
>>> f = Foo()
>>> f.x = D()
>>> f.x
5
因此,如果您觉得有必要这样做,您可以实现它。这不是默认行为,仅仅是因为它不是描述符的设计目的。