我想练习递归和装饰器并尝试执行这个简单的功能,但它不起作用:
def dec(func):
def wrapper(number):
print("Recursive count:")
rec_cou(number)
return wrapper
@dec
def rec_cou(number):
""" Count from 0 to a given number from 50 and up """
if number == 0:
print(number)
return number
num = rec_cou(number - 1)
print(num + 1)
return num + 1
rec_cou(53)
单独的递归函数效果很好,但是当我添加装饰器时会生成错误:超出最大递归深度
最佳答案
你的装饰器有两个问题:
- 您尝试调用装饰函数,在装饰器内再次有效地调用包装函数,因此您有一个无限递归循环;改为调用原始函数
func
。 - 对于外部来说,修饰函数的行为应该与原始函数一样,特别是它应该返回其结果;否则,尝试添加数字和
None
时会出现类型错误
另外,目前你的装饰器没有计算任何东西......试试这个:
def dec(func):
func.count = 0 # give each decorated function its own counter
def wrapper(number):
print("Recursive count: %d" % func.count)
func.count += 1 # increase counter
return func(number) # call original function 'func' and return result
return wrapper
更新:从你的评论来看,我似乎误解了你的装饰器应该做什么,而你也误解了装饰器的工作原理。当您第一次调用该函数时,装饰器不会被调用一次,但它会用装饰器中定义的函数替换该函数。换句话说,
@dec
def foo(...):
...
相当于
def foo(...):
...
foo = dec(foo)
即当函数被装饰时,装饰器只会被调用一次,并且每次调用原始函数时都会调用装饰器中构造的函数,并替换它。如果您只想打印一次,请使用其他答案中的装饰器,或者根本不使用装饰器:只需创建一个打印然后调用该函数的包装器。这对于为递归函数提供“入口点”来说并不罕见。
def print_and_run(number):
print("Recursive count:")
rec_cou(number)
顺便说一句,这是我通常用来可视化递归调用的装饰器:
def trace(f):
trace.depth = 0
def _f(*args, **kwargs):
print " " * trace.depth, ">", f.__name__, args, kwargs
trace.depth += 1
res = f(*args, **kwargs)
trace.depth -= 1
print " " * trace.depth, "<", res
return res
return _f
关于Python:装饰简单的递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25596573/