方法注入不起作用
Method injecting not working
我正在尝试注入我的方法而不是其他方法,但它只适用于参数数量较少的方法。
我的注射器:
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 也没有执行。
那么,我可以问你两个问题吗?
- 如何用我的方法正确替换Logger.exception?
- 如何在我的方法中正确调用原来的Logger.exception,如何
正确地将参数传递给原始函数?
您遇到的根本问题是您将 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):
...
我正在尝试注入我的方法而不是其他方法,但它只适用于参数数量较少的方法。
我的注射器:
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 也没有执行。
那么,我可以问你两个问题吗?
- 如何用我的方法正确替换Logger.exception?
- 如何在我的方法中正确调用原来的Logger.exception,如何 正确地将参数传递给原始函数?
您遇到的根本问题是您将 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):
...