[英]How to use a decorator of a descriptor within a sub class
我想知道是否可以在子类中使用描述符的装饰器。
class Descriptor():
def __get__(self, instance_obj, objtype):
raise Exception('ouch.')
def decorate(self, f):
print('decorate', f)
return f
class A():
my_attr = Descriptor()
class B():
@my_attr.decorate
def foo(self):
print('hey, whatsup?')
# --> NameError: name 'my_attr' is not defined
当然,这不起作用,因为在B
的类定义中未定义my_attr
。
接下来我尝试了:
class B():
@A.my_attr.decorate
def foo(self):
print('hey, whatsup?')
# --> Exception: ouch.
但是,这种方法调用描述符__get__
方法(其中instance_obj
参数为None
),因此触发了测试异常。 要访问装饰器,可以检查instance_obj
None
为返回描述符本身:
def __get__(self, instance_obj, objtype):
if instance_obj is None:
return self
raise Exception('avoid this')
# --> decorate <function B.foo at 0x1021dd7b8>
有用! 但它是否合理或有没有办法在B
的类定义中使用装饰器?
您可以通过从类的__dict__
映射中检索原始对象来完全绕过描述符协议:
A.__dict__['my_attr'].decorate
或清洁,使用vars()
:
vars(A)['my_attr'].decorate
然而, @
修饰语法不允许订阅(您将得到与属性访问,并在年底的单一调用仅简单表述),所以你必须提取词典第一 :
_A_my_attr = vars(A)['my_attr']
@_A_my_attr.decorate
def foo(self):
# ...
但是,除非必须捕获对类的绑定,否则最好保护__get__
的第一个参数为None
,如您所发现的那样。 这正是property
对象或函数的作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.