问题描述
这是(简化的)案例:
>>> inst = Foo()
>>> inst.sub.bar()
它从子类的 bar() 方法返回了一些很棒的东西。
这是这样写的:
class Sub() :
def __init__(inst) :
self.inst = inst
def bar(self) :
'''does something magnificent with the Foo instance (self.inst)'''
return smtg
class Foo() :
def __init__(self,*args,**kwargs):
self.sub = Sub(self)
当在第三类中使用 Foo 来处理特定的东西时:
class superFoo(Foo) :
def specific(self,*a,**kw) :
...
我还想使用@decorator 将特定方法包装在子类中,就像我对 Foo 所做的那样:
from functools import wraps
def add_method(cls):
def decorator(func):
@wraps(func)
def wrapper(self,**kwargs):
return func(self,**kwargs)
setattr(cls,func.__name__,wrapper)
return decorator
@add_method(superFoo)
def spam(self,**kwargs) :
return self.specific() + ...
>>> inst = superFoo()
>>> inst.spam() # yep
但我想要的是这个:
>>> inst.sub.spam()
所以我试过:
@add_method(superFoo)
def spam(self,**kwargs) :
return self.inst.specific() + ...
在 add_method 函数中:
setattr(cls.sub,wrapper) # ouch,sub not instantiated
失败。
我可以 sublass Sub(实际上我现在已经这样做了)来满足需求:
class superSub(Sub) :
def spam(self,**kwargs) :
return self.inst.specific() + ...
class superFoo(Foo) :
def __init__(self,**kwargs):
super().__init__(*args,**kwargs) # there is actualy other inheritances
self.sub = superSub(self) # replaces Sub() by its subclass
但我想知道是否可以使用装饰器(如果可能的话):add_method
会在需要时导入到模块中,并且在查看代码时会第一眼看到模块的具体内容:
from abyssal import add_method
class superFoo(Foo) : # folded in my editor
@add_method(superFoo) :
def spam(self) : # folded
非常感谢
解决方法
您的 add_method
装饰器可能是您的 superFoo
类的方法:
class superFoo(Foo):
def add_method(self):
def decorator(func):
setattr(self,func.__name__,func)
return func
return decorator
(注意我简化了一点)
然后您将其用作:
sub = Sub()
inst = superFoo(sub)
@inst.add_method(superFoo)
def spam(self,*args,**kwargs) :
return self.inst.specific() + ...
但又一次。我建议使用继承。只需为 Sub
定义子类会更简单易懂。