gpt4 book ai didi

Python 函数跟踪

转载 作者:太空宇宙 更新时间:2023-11-03 12:29:21 27 4
gpt4 key购买 nike

为了让递归的过程更直观,这个例子是given :

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

def trace(f):
f.indent = 0
def g(x):
print('| ' * f.indent + '|--', f.__name__, x)
f.indent += 1
value = f(x)
print('| ' * f.indent + '|--', 'return', repr(value))
f.indent -= 1
return value
return g


fib = trace(fib)
print(fib(4))

我能理解 trace 函数“做什么”,但不明白“怎么做”。具体来说:

1) 为什么我们使用 f.indent 而不是简单的 indent = 0(好吧,我知道那行不通,但我不明白为什么)。

2)我不明白怎么办

print('|  ' * f.indent + '|--', 'return', repr(value))

直到找到一个值才执行。

有人愿意彻底解释整个事情吗?

最佳答案

哇哦。好的,我们开始吧!

首先,你有一个函数,任何函数。在您的例子中,这是 fib()。现在,在 python 中,函数也是对象,它们可以在运行时创建,所以我们实际上可以这样做:

def give_me_a_function():
def f(x):
return x

return f

(警告:对于此答案的其余部分,“功能”一词的可怕重复)。

好吧,我们定义了一个不接受参数并返回的函数,...另一个函数?这是正确的!函数是对象!您可以在运行时创建它们!因此,我们在原始函数中定义了第二个函数,并像返回任何其他对象一样返回它。

现在,让我们做一些更复杂的事情:

def alter(other_function):
def altered(x):
return other_function(x) + 1

return altered

那是什么鬼?

好吧,我们定义了一个函数,alter()。就像上面的例子一样,它在运行时创建一个函数并将它作为对象返回。我们已经介绍了这么多。

现在,如果函数是对象,并且可以创建和返回,为什么不能将其作为参数传递?并调用它,当你在它的时候!没错:alter() 接受一个函数作为参数 (*),并使用它。

alter() 所需要做的就是将上述魔法与这个新魔法结合起来:我们接收一个函数作为参数,即时创建另一个使用它的函数,然后返回这个新的函数对象!

让我们试试吧。

>>> def f(x):
... return 2*x
>>> new_function = alter(f)
>>> f(2)
4
>>> new_function(2)
5

到此为止! alter() 采用我的 f(),创建一个将返回 f() + 1 的新函数,并将其作为返回值。我将它分配给 new_function,并且我有一个新的、自制的、运行时创建的函数。

(我确实警告过你使用“函数”这个词,不是吗?)

现在,到您的代码段。您正在做的事情比 f() + 1 更复杂。或不?那么,您正在创建一个新函数,它接受原始函数、调用它并打印一些数据。这并不比我们刚才做的更神奇。最大的区别在哪里?

好吧,有一个细节:fib() 是递归的,所以它会调用自身,对吗?没有!不是本身。它调用 fib(),而您碰巧这样做了:

fib = trace(fib)

哇哦。 fib() 不再是它自己了! 现在 fib()trace(fib)!因此,当 fib() 进入递归时,它不会调用自身,而是调用我们创建的自身的包装版本。

这就是为什么要这样处理缩进的原因。再看看 trace(),现在知道它实际上是递归缩进的,这很有意义,不是吗?你想在递归的每一层都有一个缩进,所以递增它,调用 fib()(记住,现在是 trace(fib)),然后当我们' 回来(所以递归来了又来,我们即将返回到调用链中的前一步)我们递减它。

如果您仍然看不到它,请尝试将所有功能移至 fib()。忘掉装饰功能吧,那简直令人困惑。

啊。我真的希望这会有所帮助,而且 2000 名比我先回答的人并没有让这个问题过时。

干杯!

(*) Yeah yeah duck typing yadda yadda callable objects bla bla irrelevant.

关于Python 函数跟踪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5537425/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com