首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >python装饰器是如何定义的?

python装饰器是如何定义的?
EN

Stack Overflow用户
提问于 2017-11-25 14:16:19
回答 1查看 61关注 0票数 0

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

TL;博士

代码语言:javascript
运行
复制
is decorator func1 = func2(func1) # True
is decorator func3 = func2(func1) # ???

让我们看一下维基,它描述了两种等价的函数装饰方法:

代码语言:javascript
运行
复制
@viking_chorus
def menu_item():
    print("spam")

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

现在,让我们看看这个网站上的描述,特别是回到装饰器的部分。定义了两种功能:

代码语言:javascript
运行
复制
def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner

def ordinary():
    print("I am ordinary")

然后,作者对函数进行修饰,并将其称为:

代码语言:javascript
运行
复制
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary

我们可以注意到作者没有使用:

代码语言:javascript
运行
复制
>>> ordinary = make_pretty(ordinary)

这是Wiki推荐的方法(我知道Wiki有时是错误的)。因此,我决定使用最后一种方式来装饰取自这个教程的斐波纳契数函数。

代码语言:javascript
运行
复制
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)

这一呼吁:

代码语言:javascript
运行
复制
>>> fib_element = memoize(fib)
>>> fib_element(40)

在我的机器上需要很长时间,这意味着fib()没有被正确地装饰。执行时间与fib(40)相当。这些电话:

代码语言:javascript
运行
复制
>>> fib = memoize(fib)
>>> fib_element = fib # assigned after decoration
>>> fib(40)
>>> fib_element(40)

快执行。所以问题是:我们是否可以说,我们在ordinary赋值中装饰了pretty = make_pretty(ordinary)函数?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-25 14:24:20

fib_element(40)的第一次调用之所以缓慢,是因为您没有递归地修饰:fib函数不知道您的回忆录。如果在同一个元素上重复调用fib_element,则第一个调用将是缓慢的,其他调用非常快。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47486953

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档