Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么decorator中的递归函数调用其内部函数_Python_Python 3.x_Recursion_Closures_Decorator - Fatal编程技术网

Python 为什么decorator中的递归函数调用其内部函数

Python 为什么decorator中的递归函数调用其内部函数,python,python-3.x,recursion,closures,decorator,Python,Python 3.x,Recursion,Closures,Decorator,为什么在第4行递归func(n)调用internal函数n次,而不仅仅是原始函数fact def log(func): def inner(n): print('inner()') result = func(n) return result return inner def fact(n): return 1 if n < 2 else n*fact(n-1) fact = log(fact) if __nam

为什么在第4行递归
func(n)
调用
internal
函数n次,而不仅仅是原始函数
fact

def log(func):
    def inner(n):
        print('inner()')
        result = func(n)
        return result
    return inner

def fact(n):
    return 1 if n < 2 else n*fact(n-1)

fact = log(fact)

if __name__ == '__main__':
    fact(4)
第行
fact=log(fact)
decorator
log
返回对
内部
函数对象的引用。此引用被分配给name
fact
fact.\uuuu name\uuuu
现在打印
内部
。另外,当我检查
id(fact)
时,它会返回新值

内部装饰的
fact
函数自由变量
func
仍然指向原始
fact
函数对象。我可以通过使用
id(func)
func.\uuuu name\uuuu
inside
inside
来确定它,它与之前一样。那部分我就是不明白。当递归函数在
result=func(n)
inside
inner
行中运行时,
func(n)
调用的
fact
(或
inner
)不是原始的
fact
。这让我很困惑,因为
func
仍然指向原始的
事实

def log(func):
    def inner(n):
        print('inner()')
        result = func(n)
        return result
    return inner

def fact(n):
    return 1 if n < 2 else n*fact(n-1)

fact = log(fact)

if __name__ == '__main__':
    fact(4)

为什么decorator内部的递归函数调用其内部函数,而不是原始函数,该函数已传递给decorator,并且仍然引用它?

正如@khelwood已经解释的
internal()
被打印4次,因为递归调用
内部
函数4次,很容易

您的
fact
函数在
internal
函数内的
result=func(n)
行中被调用。如果您
打印(事实名称)
输出为
内部
,因为
事实
内部
功能

这可能会让人困惑,因为您在
log
decorator中传递的每个函数都将成为
内部
函数。 为了避免这种混淆,我建议像这样使用
wrapps
decorator:

from functools import wraps
def log(func):

    @wraps(func)
    def inner(n):
        print('inner()')
        result = func(n)
        return result
    return inner

这样,您在装饰器内部传递的
func
将保持原始身份,并且
打印(事实.\uuuu姓名.\uuuuuuuuu)
将打印
事实

内部
替换
事实
。对
事实
的任何递归调用都是对
内部
的调用。它实际上调用了这两个函数,但
事实
内部
调用中被调用。如果我调用
func.\uuu name\uuuu
id(func)
内部
,它将打印
事实
,并且仍然引用原始函数。那么为什么
func(n)
调用
internal
?因为
fact
既是函数名也是变量名。你不应该这样做,因为这让人困惑。当您写入
fact
时,它引用的是变量,而不是函数,并且由于变量
fact
的值是
log(fact)
因此调用
log
函数并返回
internal
。因此,使用类似于
logging\u fact
的方法更改变量的名称会更清晰。@edzoons基本上你的
log()
所做的就是返回一个
internal
func,你分配给
log()
的任何变量都将是一个内部函数。你覆盖了
事实
名称,这是不应该做的。我终于明白了,你们俩(@JLeno46和@khelwood)想对我说的话。原始的
fact
函数加载全局名称
fact
,顺便说一句,它是修饰的
fact
。谢谢。@khelwood如果我将名称
fact
更改为
logging\u fact
,函数将不再修饰。尽管如此,它还是帮助我理解了它。
def log(func):
    def inner(n):
        print('inner()')
        result = func(n)
        return result
    return inner

def fact(n):
    return 1 if n < 2 else n*fact(n-1)

fact = log(fact)

if __name__ == '__main__':
    fact(4)