我想创建一个可以与参数一起使用的Python装饰器:
@redirect_output("somewhere.log")
def foo():
....
Run Code Online (Sandbox Code Playgroud)
或没有它们(例如,默认情况下将输出重定向到stderr):
@redirect_output
def foo():
....
Run Code Online (Sandbox Code Playgroud)
那可能吗?
请注意,我不是在寻找重定向输出问题的不同解决方案,它只是我想要实现的语法的一个示例.
from functools import wraps
def foo_register(method_name=None):
"""Does stuff."""
def decorator(method):
if method_name is None:
method.gw_method = method.__name__
else:
method.gw_method = method_name
@wraps(method)
def wrapper(*args, **kwargs):
method(*args, **kwargs)
return wrapper
return decorator
Run Code Online (Sandbox Code Playgroud)
例如:下面的装饰my_function用foo_register的,而不是它曾经做对decorator.
@foo_register
def my_function():
print('hi...')
Run Code Online (Sandbox Code Playgroud)
示例:以下按预期工作.
@foo_register('say_hi')
def my_function():
print('hi...')
Run Code Online (Sandbox Code Playgroud)
如果我希望它在两个应用程序中正常工作(一个使用method.__name__和一个传递名称),我必须检查内部foo_register是否第一个参数是装饰器,如果是,我必须:( return decorator(method_name)而不是return decorator).这种"检查它是否可以调用"似乎非常hackish.有没有更好的方法来创建这样的多用途装饰器?
PS我已经知道我可以要求装饰器被调用,但这不是一个"解决方案".我希望API感觉自然.我的妻子喜欢装饰,我不想破坏它.
下面是我的@logged()装饰器制造商。它的工作原理大致如下:
logger实例和一个disabled标志。disabled是False,则在装饰函数之前/之后输出一些日志。disabled是True,则它不输出任何内容并抑制logger装饰函数的 。无论是logger和disabled参数有自己的缺省值。但是,当我想使用默认值时,我仍然需要写空括号,如下所示:
@logged()
def foo():
pass
Run Code Online (Sandbox Code Playgroud)
当我只想要默认参数时,有没有办法摆脱这些空括号?这是我想要的一个例子:
@logged
def foo():
pass
@logged(disabled=True)
def bar():
pass
Run Code Online (Sandbox Code Playgroud)
@logged()装饰器制造商的代码:
import logging
import logging.config
from functools import wraps
def logged(logger=logging.getLogger('default'), disabled=False):
'''
Create a configured decorator that controls logging output of a function
:param logger: the logger to send output to
:param disabled: True if the logger should …Run Code Online (Sandbox Code Playgroud)