为什么在decorator中返回函数时没有参数。

2024-04-23 11:23:01 发布

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

示例: 带memoize decorator的Fibonaci递归函数。调用函数helper时没有参数。如果函数helper被定义为接受一个参数x,那么我希望用一个参数调用函数。我想知道为什么语法是这样的?你知道吗

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

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

print(fib(40))

Tags: 函数helper示例参数returnif定义def
2条回答

您确实用参数调用了助手。装饰者是这个的语法糖

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


fib = memoize(fib)

所以您的fib函数不再是原来的fib-函数。它实际上是helper闭包,因为memoize返回的就是闭包。所以,当你调用fib(40)的时候,你可以调用helper(40)memoize装饰器创建一个函数对象,它不调用它,只返回它。你知道吗

我相信语法是这样的,所以它看起来尽可能简化。将decorator对象放在@(一个接受一个参数并返回一个函数的函数)之后,python用您定义的函数调用它。这个

@memoize
def fib(n):
    ...

完全等效于以下内容,不使用magic decorator语法:

def fib(n):
   ...

fib = memoize(fib)

如果你想让你的头旋转一点,考虑一下@后面实际上可以跟一个函数调用,但是这个函数调用必须返回一个如上所述的decorator!下面是一个愚蠢的例子,它计算装饰函数被调用的次数,但允许您设置起始值。(这只是一个例子:它不是很有用,因为只有一个函数可以修饰,等等)

def countcalls(start):
    global _calls
    _calls = start
    def decorator(f):
        def wrapper(x):
            global _calls
            _calls += 1
            return f(x)
        return wrapper
    return decorator

@countcalls(3)
def say(s):
    print(s)

say("hello")
# _calls is now 4

这里,countcalls(4)定义并返回(不调用)函数decorator,它将包装修饰的函数并返回包装器来代替我编写的函数。你知道吗

相关问题 更多 >