假设我有两个类Child
和Parent
(这是Child
的基类)。我还有另一个类Dec
,其中包含一个装饰器dec
,我想在Parent
方法中使用它。我希望能够指定Dec
中应使用的Child
对象。
这是我到目前为止尝试过的:
class Dec():
def dec(self, func):
def wrapper(self):
print("Before func call")
func(self)
print("After func call")
return wrapper
class Parent():
dec = None
@dec.dec
def p(self):
print('hello')
dec = Dec()
class Child(Parent):
a = dec
t = Child()
t.p()
所以,我得到了
AttributeError: 'NoneType' object has no attribute 'dec'
在@dec.dec
。
是否可以选择在Child
类中使用带有装饰器的类?
答案 0 :(得分:0)
您在这里遇到的问题与范围界定有关。
运行此代码时,我收到此错误:
"ignore_above": 256
使用它,您可以看到自己存在一些范围界定问题。在此文件中,您多次定义...<stack trace>...
File ".\__main__.py", line 10, in <module>
class Parent():
File ".\__main__.py", line 13, in Parent
@dec.dec
AttributeError: 'NoneType' object has no attribute 'dec'
。与其像在第11行上那样实例化dec
,不如将Dec
定义为Dec.dec(...)
,可以从类本身调用它,而不仅仅是类的实例。
这是一个可能的解决方案:
@classmethod
这提供了我认为是预期的行为:
class Dec():
@classmethod
def dec(self, func):
def wrapper(self):
print("Before func call")
func(self)
print("After func call")
return wrapper
class Parent():
@Dec.dec
def p(self):
print('hello')
class Child(Parent):
pass # you didn't really need anything here.
t = Child()
t.p()
答案 1 :(得分:0)
作为另一种解决方案的替代方法,这是另一种方法:
为您的流程定义某种通用结构,然后为您的类更改“装饰器”或“扩展处理器” ...
class Parent:
extended_processor = None
def p(self):
if (self.extended_processor is not None and
hasattr(self.extended_processor, "before") and
callable(self.extended_processor.before)):
self.extended_processor.before()
print('parent says hello')
if (self.extended_processor is not None and
hasattr(self.extended_processor, "after") and
callable(self.extended_processor.after)):
self.extended_processor.after()
class ex_proc:
@classmethod
def before(cls):
print("ex_proc before")
@classmethod
def after(cls):
print("ex_proc after")
class Child(Parent):
extended_processor = ex_proc
print("\n=== PARENT ===")
par = Parent()
par.p()
print("\n=== CHILD ===")
chi = Child()
chi.p()
这提供了以下输出:
=== PARENT ===
parent says hello
=== CHILD ===
ex_proc before
parent says hello
ex_proc after