当一个定义描述符值检索等被覆盖时,使描述符的实例实际上不可访问。
即一个人不会写instance_with_descriptor_attr.descriptor_attr.some_method_on_descriptor()
...不会工作。我的问题基本上是如何仍然可以访问描述符的实例......
当一个定义描述符值检索等被覆盖时,使描述符的实例实际上不可访问。
即一个人不会写instance_with_descriptor_attr.descriptor_attr.some_method_on_descriptor()
...不会工作。我的问题基本上是如何仍然可以访问描述符的实例......
正如 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
它适用于属性描述符的原因可以在文档中的示例属性描述符实现中看到: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)
产量(如果您使用的是 python shell,则必须重新定义类)
o = Test()
>>> print o.x
5
>>> print Test.x
<__main__.Desc object at 0x23205d0>
你需要去上课本身:
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>
如果__get__
描述符的方法没有“ return self
”语句,那么描述符只能通过__dict__
类的属性访问:
class descriptor:
def __get__(self, instance, owner=None):
return 1
class A:
d = descriptor()
a = A()
a.d # --> 1
A.d # --> 1
A.__dict__['d'] # --> <__main__.descriptor object at ...>