我正在尝试注入我的方法而不是另一种方法,但它仅适用于参数数量较少的方法。
我的注射器:
def inject(target_function, new_function):
@wraps(target_function)
def _inject(*args, **kwargs):
return new_function(target_function, *args, **kwargs)
return _inject
# decorator injection.
def inject_to(target_object, target_function_name):
def _inject_to(new_function):
target_function = getattr(target_object, target_function_name)
setattr(target_object, target_function_name, inject(target_function, new_function))
return new_function
return _inject_to
原始方法,我想用我的方法替换:
@macros.macro
class Logger:
__qualname__ = 'Logger'
suppress = False
def exception(self, message, *args, exc=None, log_current_callstack=True, level=150, owner=None, trigger_breakpoint=False):
if Logger.suppress:
return
我的方法:
@injector.inject_to(Logger, 'exception')
def exception(original, self, *args, **kwargs):
f.writeLine("Logger.exception !!!")
f.writeLine("original" + str(original))
f.writeLine("self" + str(self))
f.writeLine("args" + str(*args))
f.writeLine("kwargs" + str(**kwargs))
此注入器适用于def update_progress(self):
等函数,但对于Logger.exception,它不起作用。
有趣的时刻 - 当我的方法被注入时,它不起作用,并且原始方法Logger.exception也不会执行。
那么,我可以问你两个问题吗?
答案 0 :(得分:3)
您遇到的根本问题是您将inject
的输出分配给方法属性。 inject
的结果始终接受原始函数作为其第一个参数,而始终使用self
作为第一个参数调用方法。世界上没有任何装饰者会为你改变这一点,所以你必须解决它。
行inject_to
中setattr(target_object, target_function_name, ...)
分配的任何内容都必须接受self
作为第一个参数。只需先重写_inject
即可接受self
。也许允许两个版本并向inject
添加布尔参数。同时将参数的顺序更改为您的exception
版本:
def inject(target_function, new_function, method=False):
if method:
@wraps(target_function)
def _inject(self, *args, **kwargs):
return new_function(self, target_function, *args, **kwargs)
else:
@wraps(target_function)
def _inject(*args, **kwargs):
return new_function(target_function, *args, **kwargs)
return _inject
...
setattr(target_object, target_function_name, inject(target_function, new_function, method=True))
...
@injector.inject_to(Logger, 'exception')
def exception(self, original, *args, **kwargs):
...