python装饰器实际上是如何定义的?

python装饰器实际上是如何定义的?,python,decorator,Python,Decorator,首先,我知道什么是装饰师。我想了解一些小方面 TL;DR is decorator func1 = func2(func1) # True is decorator func3 = func2(func1) # ??? 让我们看看哪种方法描述了修饰函数的两种等效方法: @viking_chorus def menu_item(): print("spam") def menu_item(): print("spam") menu_item = viking_chorus(m

首先,我知道什么是装饰师。我想了解一些小方面

TL;DR

is decorator func1 = func2(func1) # True
is decorator func3 = func2(func1) # ???

让我们看看哪种方法描述了修饰函数的两种等效方法:

@viking_chorus
def menu_item():
    print("spam")

def menu_item():
    print("spam")
menu_item = viking_chorus(menu_item)
现在,让我们来看看这方面的描述,特别是在回到装饰师一节中。定义了两个功能:

def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner

def ordinary():
    print("I am ordinary")
然后作者装饰函数并调用它:

>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary
我们可以注意到作者没有使用:

>>> ordinary = make_pretty(ordinary)
这是Wiki推荐的方法(我知道Wiki有时可能是错误的)。所以我决定用最后一种方法来装饰斐波那契数函数,该函数取自:

此电话:

>>> fib_element = memoize(fib)
>>> fib_element(40)
在我的机器上花费了很长时间,这意味着
fib()
没有正确装饰。执行时间与
fib(40)
相当。这些呼吁:

>>> fib = memoize(fib)
>>> fib_element = fib # assigned after decoration
>>> fib(40)
>>> fib_element(40)

快速执行。所以问题是:我们可以说我们在
pretty=make_pretty(普通)
赋值中修饰
normal
函数吗?

第一次调用
fib_元素(40)
很慢的原因是你没有递归地修饰:
fib
函数不知道你的记忆。如果在同一个元素上重复调用
fib_元素
,第一个调用会很慢,其他调用会很快


由于
fib
调用
fib
(在第二个示例中指的是修饰函数,但在第一个示例中指的是原始函数),因此您需要给它取相同的名称,以便使用此修饰方法从记忆中获益。

第一次调用
fib\u元素的原因(40)
之所以慢,是因为您没有递归地装饰:
fib
函数不知道您的备忘录。如果在同一个元素上重复调用
fib_元素
,第一个调用会很慢,其他调用会很快


由于
fib
调用
fib
(在第二个示例中指的是修饰函数,但在第一个示例中指的是原始函数),因此您需要给它取相同的名称,以便使用此修饰方法从记忆中获益。

从技术上讲,没有称为修饰器的不同对象;它实际上只是一个函数,将一个函数作为参数并返回(或预期返回)另一个函数。特殊的是decorator语法,它提供了一种应用decorator函数的简洁方法
@foo def bar():…
def bar()短:。。。;bar=foo(bar)
。从技术上讲,没有称为装饰器的独特对象;它实际上只是一个函数,将一个函数作为参数并返回(或预期返回)另一个函数。特殊的是decorator语法,它提供了一种应用decorator函数的简洁方法
@foo def bar():…
def bar()短:。。。;bar=foo(bar)
。因此,如果
fib
函数在第一次调用期间不知道记忆,为什么第二次和下一次使用相同参数的调用(如您所述)使用字典,而
fib\u元素(N)
工作得很快?这表明
fib
知道记忆化。因为
fib
现在是记忆化的
fib
。实际上
fib\u element=fib
只使两个名称指向非常相同的函数,它们不是不同的函数。因此,如果
fib
函数在第一次调用期间不知道记忆化,为什么具有相同参数的第二个和下一个调用(如您所述)使用字典,而
fib\u元素(N)
工作得很快?这表明
fib
知道记忆。因为
fib
现在是记忆化的
fib
。实际上
fib\u element=fib
只是使这两个名称指向非常相同的函数,它们不是不同的函数。
>>> fib = memoize(fib)
>>> fib_element = fib # assigned after decoration
>>> fib(40)
>>> fib_element(40)