【问题标题】:Understanding Python Descriptors了解 Python 描述符
【发布时间】:2015-04-28 20:41:42
【问题描述】:

我正在努力更好地理解描述符。

我不明白为什么在 foo 方法中描述符 __get__ 方法没有被调用。

据我了解描述符,当我通过点运算符访问对象属性或使用 __getattribute__() 时,总是会调用 __get__ 方法。

根据Python documentation

class RevealAccess(object):
    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print('Retrieving', self.name)
        return self.val

    def __set__(self, obj, val):
        print('Updating', self.name)
        self.val = val

class MyClass(object):
    x = RevealAccess(10, 'var "x"')
    y = 5

    def foo(self):
        self.z = RevealAccess(13, 'var "z"')
        self.__getattribute__('z')
        print(self.z)

m = MyClass()
m.foo()
m.z # no print
m.x # prints var x

【问题讨论】:

  • 我不太明白你的问题是什么?
  • @user3467349: m.zm.x 都是类 RevealAccess 的实例,它实现了描述符协议。 OP 期望该协议同时用于 m.zm.x
  • @user3467349:例如在回答问题之前,您需要了解描述符协议是什么
  • m.z 准确返回为我分配给它的实例,我仍然不确定这里的预期输出是什么?
  • 他的意思是打电话给m.z.__getattribute__ 吗? MyClass 不是 RevealClass 的子类...

标签: python descriptor python-descriptors


【解决方案1】:

zinstance 上的属性,而不是类上的属性。描述符协议仅适用于从类中检索到的属性。

来自Descriptor HOWTO

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

在 Python 数据模型的 Implementing Descriptors section 中:

以下方法仅适用于包含该方法的类(所谓的 descriptor 类)的实例出现在 owner 类中(描述符必须位于所有者的类字典或在其父母之一的类字典中)。

您的m.z 在类字典中找不到; type(m).__dict__['z'] 不存在;而是在m.__dict__['z'] 中找到它。这里m是实例,owner类是MyClassz没有出现在owner类字典中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2015-05-19
    相关资源
    最近更新 更多