为什么在使用obj.x语法调用时不调用Python描述符方法?

时间:2015-01-26 18:16:27

标签: python python-3.x descriptor

我这里有一个描述符类X。我尝试在另一个类X

中使用描述符Y
class X:
    def __init__(self, value):
        self.value = value

    def __get__(self, instance, owner):
        print('#### X.__get__ ####')
        return self.value

    def __set__(self, instance, value):
        print('#### X.__set__ ####')
        self.value = value

class Y:
    def __init__(self):
        self.x = X(10)

y = Y()
print(y.x)
y.x = 20

我希望语句print(y.x)会调用x.__get__而语句y.x = 20会调用x.__set__,但它不会发生。当我运行上面的程序时,我只是得到了这个输出。

<__main__.X object at 0x7fc65f947950>

为什么没有调用描述符方法?

1 个答案:

答案 0 :(得分:3)

要调用描述符协议方法,您需要将描述符实例(X()放在您的案例中)放在Y 上,而不是放在实例上。 Raymond Hettinger在Descriptor HowTo Guide中对此进行了详细描述:

  

对于对象,机器位于object.__getattribute__(),将b.x转换为type(b).__dict__['x'].__get__(b, type(b))

注意b.x如何转换为通过 type(b) 的dict访问获得的描述符的调用。 Y类应该如下所示:

class Y:
    x = X(10)

但是,由于X的所有实例都将共享Y的单个实例,因此需要修改X描述符类以从{{获取和设置值1}}而不是instance