from functools import wraps
def logged(func):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging
@logged
def f(x):
"""does some math"""
return x + x * x
print f.__name__ # prints 'f'
print f.__doc__ # prints 'does some math'
鉴于此示例代码,我将如何执行 @logged(variable)
?
我试过了
from functools import wraps
def logged(func):
def outer(var):
@wraps(func)
def with_logging(*args, **kwargs):
print func.__name__ + " was called"
return func(*args, **kwargs)
return with_logging
return outer
我希望像这样执行:logged(func)(session_variable)
但是不起作用。 任何的想法?我希望能够执行@logged 和@logged(var)(甚至@logged(var1, var2)) 谢谢。
最佳答案
这里的诀窍是,你必须反省你得到的东西:
def logged(*setting_args, **setting_kwargs):
no_args = False
if len(setting_args) == 1 \
and not setting_kwargs \
and callable(setting_args[0]):
# We were called without args
func = setting_args[0]
no_args = True
def outer(func):
@wraps(func)
def with_logging(*args, **kwargs):
print "{} was called".format(func.__name__)
print "Setting args are: {}".format(setting_args)
print "Setting keyword args are: {}".format(setting_kwargs)
return func(*args, **kwargs)
return with_logging
if no_args:
return outer(func)
else:
return outer
这将适用于以下任何一项:
# No arguments
@logged
def some_function(x):
pass
# One or more arguments
@logged(1, 2, 3)
def some_function(x):
pass
# One or more keyword arguments
@logged(key=1, another_key=2)
def some_function(x):
pass
# A mix of the two
@logged(1, 2, key=3)
def some_function(x):
pass
如果只用一个可调用参数调用它,它将不会工作:
# This will break.
@logged(lambda: "Just for fun")
def some_function(x):
pass
无法区分单个可调用设置和装饰器的无参数调用之间的区别。但是,如果需要,您可以传递一个垃圾关键字 arg 来解决这个问题:
# This gets around the above limitation
@logged(lambda: "Just for fun", ignored=True)
def some_function(x):
pass
关于Python装饰器可选参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17119154/