基本上,我希望一个具有参数列表的decorator不仅包含一个函数,还可以从@-和正则形式调用它。我已经“设计”了一个快速的解决方案,但它很难看,并立即以@形式执行一个函数,这是一个不希望的副作用(当然,这是由于返回body 2()所致)。
def status_display_with_comment(comment, closure = None):
def body_one(function = None):
def body_two():
print(comment)
#an ugly workaround to be able to run both the @- and regular forms
if function != None:
print("Entering", function.__name__)
function()
print("Exited", function.__name__)
elif closure != None:
print("Entering", closure.__name__)
closure()
print("Exited", closure.__name__)
return body_two()
return body_one
def a_function():
print('a_function executes')
@status_display_with_comment(comment = 'some comment')
def a_function_with_comment():
print('a_function_with_comment executes')
a_function_status_display_with_comment = status_display_with_comment(closure = a_function, comment = 'a comment')
a_function_status_display_with_comment()
提前谢谢。
附:我得把我的头绕在那整个封闭的东西上。考虑到它可以像Scheme那样递归地完成,这很有趣(对我来说很久以前)。
最佳答案
您需要一个返回decorator的函数:
def status_display_with_comment(comment):
def decorator(function):
def wrapper():
print(comment)
print("Entering", function.__name__)
result = function()
print("Exited", function.__name__)
return result
return wrapper
return decorator
def a_function():
print('a_function executes')
a_function_SD_WC = status_display_with_comment('a comment')(a_function)
a_function_SD_WC()
同样有效:
@status_display_with_comment('a comment')
def a_function():
print('a_function executes')
a_function()
常规的直接decorator已经返回一个闭包:
def a_normal_decorator(function):
def wrapper():
return function()
return wrapper
wrapper
这里是一个闭包,因为它必须保持function
在a_normal_decorator
完成执行之后。作为参考,这是一个惯用的装饰符通常是这样写的:
import functools
def decorator(function):
@functools.wraps(function)
def wrapper(*a, **kw):
return function(*a, **kw)
return wrapper
也就是说,它将参数传递给包装好的函数,而不会丢弃其返回值。
functools.wraps
将文档字符串从要包装的函数复制到包装函数__name__
、__module__
、__annotations__
和__doc__
。关于python - 此python装饰器的一种更优雅的方式,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18668381/