访问描述符实例

时间:2012-11-20 15:05:00

标签: python python-3.x

当一个人定义一个描述符值时,覆盖检索等,使得描述符的实例有效地无法访问。

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

2 个答案:

答案 0 :(得分:2)

你需要上课:

type(instance_with_descriptor_attr).descriptor_attr

演示:

>>> class Foo():
...     @property
...     def bar(self): return 'bar'
... 
>>> foo = Foo()
>>> foo.bar
'bar'
>>> type(foo).bar
<property object at 0x109f24310>

答案 1 :(得分:2)

正如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

它适用于属性描述符的原因可以在docs中的示例属性描述符实现中看到: 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)

如果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)

yield(如果你使用的是python shell,则必须重新定义类)

o = Test()
>>> print o.x
5
>>> print Test.x
<__main__.Desc object at 0x23205d0>