基本上,我希望一个具有参数列表的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这里是一个闭包,因为它必须保持functiona_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/

10-12 22:07