仅包含__get__的,是non-data descriptor, 如果实例__dict__包含同名变量, 则实例优先; 如果还包含__set__, 则是data descriptor, 优先于实例__dict__同名变量.
class c: pass class a: def __init__(self, name): self.name = name def __get__(self, ins, cls): print('call %s get: '%type(self).__name__, end='') ins.__dict__[self.name] = c() return ins.__dict__[self.name] class a2(a): def __set__(self, ins, val): ins.__dict__[self.name] = val class t: x=a('x') y=a2('y') b = t() print(b.x) print(b.x) print(b.y) print(b.y)
结果:
>>> call a get: <__main__.c object at 0x0000000002A47B00> <__main__.c object at 0x0000000002A47B00> call a2 get: <__main__.c object at 0x0000000002B27208> call a2 get: <__main__.c object at 0x0000000002B27278>