当一个人定义一个描述符值时,覆盖检索等,使得描述符的实例有效地无法访问。
即。一个人不能写instance_with_descriptor_attr.descriptor_attr.some_method_on_descriptor()
...将无法正常工作。我的问题基本上是如何仍然可以访问描述符的实例...
答案 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>