对 python 装饰器感到困惑。何时/如何称呼他们? [复制]

Posted

技术标签:

【中文标题】对 python 装饰器感到困惑。何时/如何称呼他们? [复制]【英文标题】:confused about python decorators. When/how are they called? [duplicate] 【发布时间】:2016-03-21 10:54:43 【问题描述】:

有人可以解释下面的代码 sn-p 吗?我对@memoize 的语法有点困惑。何时/如何称呼它?它有什么作用?

import functools

def memoize(fn):
    known = dict()

    @functools.wraps(fn)
    def memoizer(*args):
        if args not in known:
            known[args] = fn(*args)
        return known[args]

    return memoizer

@memoize
def fibonacci(n):
    '''Returns the nth number of the Fibonacci sequence'''
    assert(n >= 0), 'n must be >= 0'
    return n if n in (0, 1) else fibonacci(n-1) + fibonacci(n-2)

if __name__ == '__main__':
    print(fibonacci(10))

【问题讨论】:

它在代码加载期间被调用。它与具有相同: def fibonacci(n): # etc pass fibonacci = memoize(fibonacci) 你对一般的装饰器还是记忆化的装饰器感到困惑?我问是因为你基本上是在问,“这段代码有什么作用?”这太宽泛了。网上有很多解释装饰器的资源,还有here is一个关于memoization的SO问题。 memoize 缓存斐波那契计算的值。如果这些值是之前计算过的,它会从字典 known 返回它们并且不会重新计算它们。 我对何时以及如何调用函数 memoize 感到非常困惑。我读了很多次装饰器文档,但语言不是很清楚(至少对我来说不是)。 @AlexDicianu 通过用@memoize 装饰fibonacci,您实际上将斐波那契名称/变量绑定到memoize(fibonacci) 返回的函数。所以每次调用fibonacci时都会“隐式”调用memoizer,而定义fibonacci时会调用一次memoize 【参考方案1】:
@memoize
def fibonacci(n):
    ...

是一样的
def fibonacci(n):
    ...

fibonacci = memoize(fibonacci)

请参阅this stack overflow answer,详细了解装饰器的工作原理。

【讨论】:

fibonacci = memoize(fibonacci),不带参数 谢谢 LeartS,我已经更新了我的答案。

以上是关于对 python 装饰器感到困惑。何时/如何称呼他们? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

WPF 装饰层何时首次可用?

关于何时在 TypeScript 中调用装饰器的困惑

对mysql代码何时使用PDO进行注入证明感到困惑

代表困惑.. 我如何知道几个代表何时完成了他们的任务?

对何时使用 JMS(或一般的队列)与数据库感到困惑

Python装饰器的通俗理解