【发布时间】:2020-10-14 01:53:55
【问题描述】:
困扰了我很久。为什么装饰器函数要这样设计,在我看来它们过于复杂。让我们以这样的例子为例:
def dec(f):
def wrapper(a, b):
print('Hello')
f(a, b)
print('Bey')
return wrapper
@dec
def func(a, b):
print(a)
print(b)
为什么要在装饰器中添加一个函数,将功能包装在dec 函数中?我知道引擎就是这样工作的,但为什么不做一些简单的事情呢。像这样:
def dec(f, a, b):
print('Hello')
f(a, b)
print('Bey')
@dec
def func(a, b):
print(a)
print(b)
稍微改变一下引擎,让@运算符将函数名和参数作为参数传递给dec函数。使用第一个结构有什么好处,因为我们可以用同样的方式轻松装饰第二个结构?
如果您能给我一个示例,说明第二个示例无法解决问题 - 请分享您的知识。
票证已关闭,因为一些用户要求更清楚地了解问题,以帮助我解决问题。我必须说没有问题需要解决。我提出这个问题是为了收集有关装饰器设计方式为何如此的信息。这将帮助我了解我可以在未来使用现有的装饰器模型解决哪些其他问题。
很抱歉,如果您对这个问题有任何不清楚的地方。我认为听听有经验的 Python 用户对此有何看法并与不了解装饰函数中包装器用途的任何人分享他们的知识会很有趣。
【问题讨论】:
-
因为装饰器语法,
@出现在 装饰器的想法之后,装饰器是一个返回可调用对象的可调用对象,它修改传入的可调用对象的某些操作。@dec def func只是def func()...; func = deco(func)的语法糖。基本上,您是在问“为什么装饰者是装饰者” -
无论如何,你没有有定义一个函数。装饰器可以做其他事情,然后只需
return f您的想法会强制它充当包装器。 -
@IgorDragushhak 再次,因为装饰器只是一个返回可调用对象的可调用对象。它没有有 来定义包装器。你的想法会迫使它这样做。同样,语法糖是在这个想法之后出现的。您必须重新编写 2003 年之前存在的所有装饰器才能像您提供的那样工作。此外,它如何与非功能装饰器(基于类的装饰器)一起使用?
-
让
@dec(a, b)调用dec(f, a, b)而不是dec(a, b)(f)会有很大的优势。例如,将@dec和@dec()统一起来,可以更轻松地将可选参数添加到以前没有使用它们的装饰器中,并避免函数与另一个参数混淆的情况。我一直希望 Python 的装饰器语法是这样设计的。 -
这个问题提出的语义有很大的局限性。特别是,不再支持带参数的装饰器(如
@dec(a, b)),不再支持创建非函数对象的装饰器如@property。