基本上我想要一个带有参数列表的装饰器,它不仅包含一个能够从@ - 和常规形式调用的函数。我已经“设计”了一个快速的解决方法,但它很难看并立即在@ -form中执行一个函数,这是一个不受欢迎的副作用(当然是由于返回body_two())。
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()
提前致谢。
P.S。:我必须围绕整个封闭的东西。考虑到它可以像Scheme一样递送(很久以前对我来说),这很有趣。
答案 0 :(得分:6)
你想要一个返回装饰器的函数:
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()
常规直接装饰器已经返回一个闭包:
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__
,即文档字符串。