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

2024-04-19 08:34:30 发布

您现在位置:Python中文网/ 问答频道 /正文

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

TL;DR

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

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

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

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

现在,让我们看看关于这个website的描述,特别是在回到decorators一节中。定义了两个函数:

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有时会出错)。所以我决定用最后一种方法来修饰Fibonacci数函数,这个函数取自tutorial

def memoize(f):
    memo = {}
    def helper(x):
        if x not in memo:            
            memo[x] = f(x)
        return memo[x]
    return helper


def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

此呼叫:

>>> 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(ordinary)赋值中修饰ordinary函数吗?你知道吗


Tags: 方法函数makereturndefwikiprettyelement
1条回答
网友
1楼 · 发布于 2024-04-19 08:34:30

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

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

相关问题 更多 >