访问描述符实例

dom*_*om0 0 python python-3.x

当定义描述符值检索等时,将覆盖,使描述符的实例实际上无法访问。

即一个不能写instance_with_descriptor_attr.descriptor_attr.some_method_on_descriptor()......不会工作。我的问题基本上是如何仍然可以访问描述符的实例...

bj0*_*bj0 5

正如 eryksun 所指出的,Martijn 的解决方案适用于属性,但并非适用于所有描述符:

class Desc(object):
    def __init__(self, val=None):
        self.val = val

    def __get__(self, obj, cls):
        return self.val

    def __set__(self, obj, val):
        self.val = val

class Test(object):
    x = Desc(5)

>>> o = Test()
>>> print o.x
5
>>> print Test.x
5
Run Code Online (Sandbox Code Playgroud)

它适用于属性描述符的原因可以在文档中的示例属性描述符实现中看到:http : //docs.python.org/2/howto/descriptor.html#properties

关键是__get__函数:

def __get__(self, obj, objtype=None):
    if obj is None:
        return self
    if self.fget is None:
        raise AttributeError, "unreadable attribute"
    return self.fget(obj)
Run Code Online (Sandbox Code Playgroud)

如果 obj 为 None 则返回 self,它是描述符本身的实例。obj 是访问描述符的类的实例。当您从类实例访问属性时,obj 是该实例,当您从类对象访问它时,则 obj 是 None。

将之前的描述符更改为:

class Desc(object):
    def __init__(self, val=None):
        self.val = val

    def __get__(self, obj, cls):
        if obj is None:
            return self
        return self.val

    def __set__(self, obj, val):
        self.val = val

class Test(object):
    x = Desc(5)
Run Code Online (Sandbox Code Playgroud)

产量(如果您使用的是 python shell,则必须重新定义类)

o = Test()
>>> print o.x
5
>>> print Test.x
<__main__.Desc object at 0x23205d0>
Run Code Online (Sandbox Code Playgroud)