Python数据描述符不能用作实例变量吗?

时间:2016-04-29 07:37:56

标签: python python-2.7 descriptor

正如官方演示中描述的here,以下代码将打印Retrieving var "x"

class RevealAccess(object):
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.
    """

    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 MyClass1(object):
    x = RevealAccess(10, 'var "x"')

MyClass1().x

但如果x是一个实例变量,数据描述符机制将不起作用,以下代码将不会打印任何内容。

class MyClass2(object):
    def __init__(self):
       self.x = RevealAccess(10, 'var "x"')

MyClass2().x

并且,如果我按照here所述手动实现数据描述符机制,则以下代码将再次Retrieving var "x"

class MyClass3(object):
    def __init__(self):
       self.x = RevealAccess(10, 'var "x"')

    def __getattribute__(self, key):
        "Emulate type_getattro() in Objects/typeobject.c"
        v = object.__getattribute__(self, key)
        if hasattr(v, '__get__'):
            return v.__get__(None, self)
        return v

MyClass3().x

那么,默认数据描述符机制是否未按照文档描述实现?

我正在使用python 2.7.10。

1 个答案:

答案 0 :(得分:3)

描述符操作方法在这里是错误的。 Python data model具有正确的说明:

  

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

描述符必须是类属性。