在python中装饰递归函数 [英] Decorating recursive functions in python

查看:80
本文介绍了在python中装饰递归函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解修饰的递归函数是如何工作的。
对于以下代码段:

  def dec(f):
def wrapper(* argv):
print(argv,'Decorated!')
return(f(* argv))
return(wrapper)

def f(n):
print(n,'Original!')
如果n == 1:return(1)
else:return(f(n-1)+ n)

打印(f(5))
打印

dec_f = dec(f)
打印(dec_f(5))
打印

f = dec(f)
print(f(5))

输出为:

 (5,'Original!')
(4,'Original!')
(3,' '!
(2,'原始!')
(1,'原始!')
15

((5,),'装饰! ')
(5,'Original!')
(4,'Original!')
(3,'Original!')
(2,'Original!')
(1,'Original!')
15

((5,),'Decorated!')
(5,'Original!')
((4,),'Decorated!')
(4,'Original!')
((3,),'Decorated!')
(3,'Original!' ')
((2,),'装饰!')
(2,'原始!')
((1,),'装饰ed!')
(1,'Original!')
15

第一个打印f(n),因此每次递归调用f(n)时自然会打印原始。



第二个打印def_f(n),因此当n传递给包装器时,它将递归调用f(n)。但是包装器本身不是递归的,因此只打印一个装饰的。



第三个使我感到困惑,这与使用装饰器@dec相同。为什么修饰的f(n)也调用包装器五次?在我看来,def_f = dec(f)和f = dec(f)仅仅是绑定到两个相同函数对象的两个关键字。当装饰函数的名称与未装饰函数的名称相同时,还会发生其他情况吗?



谢谢!



第二个将装饰后的f称为dec_f在全球范围内。调用Dec_f,以显示 Decorated!,但在传递给dec的f函数内部,您将调用f本身,而不是dec_f。在全局范围中查找并找到了名称f,但仍在没有包装的情况下对其进行了定义,因此从那以后,仅调用f。



在3re中例如,您将修饰后的版本分配给名称f,因此当在函数f中查找名称f时,它将在全局范围内查找,找到f,现在是修饰后的版本。


I am having hard time understanding how a decorated recursive function works. For the following snippet:

def dec(f):
    def wrapper(*argv):
        print(argv, 'Decorated!')
        return(f(*argv))
    return(wrapper)

def f(n):
    print(n, 'Original!')
    if n == 1: return(1)
    else: return(f(n - 1) + n)

print(f(5))
print

dec_f = dec(f)
print(dec_f(5))
print

f = dec(f)
print(f(5))

The output is:

(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15

((5,), 'Decorated!')
(5, 'Original!')
(4, 'Original!')
(3, 'Original!')
(2, 'Original!')
(1, 'Original!')
15

((5,), 'Decorated!')
(5, 'Original!')
((4,), 'Decorated!')
(4, 'Original!')
((3,), 'Decorated!')
(3, 'Original!')
((2,), 'Decorated!')
(2, 'Original!')
((1,), 'Decorated!')
(1, 'Original!')
15

The first one prints f(n) so naturally it prints 'Original' every time f(n) is called recursively.

The second one prints def_f(n), so when n is passed to wrapper it calls f(n) recursively. But the wrapper itself is not recursive so only one 'Decorated' is printed.

The third one puzzles me, which is the same as using decorator @dec. Why does decorated f(n) calls the wrapper five times also? It looks to me that def_f=dec(f) and f=dec(f) are just two keywords bound to two identical function objects. Is there something else going on when the decorated function is given the same name as the undecorated one?

Thanks!

解决方案

As you said, the first one is called as usual.

the second one puts a decorated version of f called dec_f in the global scope. Dec_f is called, so that prints "Decorated!", but inside the f function passed to dec, you call f itself, not dec_f. the name f is looked up and found in the global scope, where it is still defined without the wrapper, so from than on, only f gets called.

in the 3re example, you assign the decorated version to the name f, so when inside the function f, the name f is looked up, it looks in the global scope, finds f, which is now the decorated version.

这篇关于在python中装饰递归函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆