Phi*_*aro 1 python decorator python-decorators
functools.wraps,以便为以后进行适当的内省和组织。wrapped_self向该__call__方法传递一个参数来实现这一点。理想的情况应该是这样的:
class A():
def __init__(self):
...
@LoggerDecorator(logger_name='test.log')
def do_something(self):
...
Run Code Online (Sandbox Code Playgroud)
到目前为止,装饰器类是(基于来自David Beazley 的 Python Cookbook 的食谱的基本记录器装饰器):
class LoggerDecorator():
def __init__(self, func, logger_name):
wraps(func)(self)
self.logger_name = logger_name
def config_logger(self):
... # for example, uses `self.logger_name` to configure the decorator
def __call__(self, wrapped_self, *args, **kwargs):
self.config_logger()
wrapped_self.logger = self.logger
func_to_return = self.__wrapped__(wrapped_self, *args, **kwargs)
return func_to_return
def __get__(self, instance, cls):
if instance is None:
return self
else:
return types.MethodType(self, instance)
Run Code Online (Sandbox Code Playgroud)
我收到的错误是指__init__显然没有识别第三个参数:
TypeError: __init__() missing 1 required positional argument: 'func'
Run Code Online (Sandbox Code Playgroud)
有人建议我应该加入func该__call__方法。但是,如果我将其作为参数放在那里,则wrapped_self无法正确读取为参数,并且出现此错误:
__call__() missing 1 required positional argument: 'wrapped_self'
Run Code Online (Sandbox Code Playgroud)
我尝试了很多方法来解决这个问题,wraps(func)(self)包括__call__:以及这个非常接近但不能完全满足所有需求解决方案的许多变体(问题是我似乎无法再访问wrapped_self)。
由于您正在实现一个接受参数的装饰器,因此 的__init__方法LoggerDecorator应该只接受配置装饰器的参数,而该__call__方法应该成为返回包装函数的实际装饰器:
class LoggerDecorator():
def __init__(self, logger_name):
self.logger_name = logger_name
self.config_logger()
def __call__(self, func):
@wraps(func)
def wrapper(wrapped_self, *args, **kwargs):
wrapped_self.logger = self.logger
func_to_return = func(wrapped_self, *args, **kwargs)
return func_to_return
return wrapper
Run Code Online (Sandbox Code Playgroud)