python - 修饰递归函数

标签 python decorator

我有一个我写的装饰器,它会为给定的函数计时。它似乎适用于任何函数,递归函数除外。

装饰器:

def tictoc(repeats=3, loops=1):
    def t(func):
        from functools import partial, wraps
        import timeit
        @wraps(func)
        def timer(*args, **kargs):
            elapsed = timeit.repeat(partial(func, *args, **kargs), repeat = repeats, number=loops)
            mine = min(elapsed)
            print "%s finished in %.5fs (%d loops, %d times) with %.5fs per loop" % (func.__name__, mine, loops, repeats, mine/loops)
        return timer
    return t

递归函数是基本的斐波那契算法。

@tictoc()
def fib(i):
    return ( 0 if i == 0 else
             1 if i == 1 else
             fib(i-1) + fib(i-2) )
fib(15)

程序失败,出现以下错误

fib finished in 0.00000s (1 loops, 3 times) with 0.00000s per loop
fib finished in 0.00000s (1 loops, 3 times) with 0.00000s per loop
fib finished in 0.00000s (1 loops, 3 times) with 0.00000s per loop
Traceback (most recent call last):
  File "decor.py", line 61, in <module>
    [fib(x) for x in range(1,50)]
  File "/home/grout/Dropbox/Python/tictoc.py", line 7, in timer
    elapsed = timeit.repeat(partial(func, *args, **kargs), repeat = repeats, number=loops)
  File "/usr/lib/python2.7/timeit.py", line 233, in repeat
    return Timer(stmt, setup, timer).repeat(repeat, number)
  File "/usr/lib/python2.7/timeit.py", line 221, in repeat
    t = self.timeit(number)
  File "/usr/lib/python2.7/timeit.py", line 194, in timeit
    timing = self.inner(it, self.timer)
  File "/usr/lib/python2.7/timeit.py", line 100, in inner
    _func()
  File "decor.py", line 59, in fib
    fib(i-1) + fib(i-2) )
TypeError: unsupported operand type(s) for +: 'NoneType' and 'NoneType'

我不明白的是装饰器是如何执行几次然后失败的。任何帮助将不胜感激。

最佳答案

装饰器返回的函数不返回任何东西。因此,虽然 fib 应该返回一个整数,但您包装的 fib 返回 None。它工作了几次,因为在没有检查 fib 的结果的情况下进行了一些递归调用,但是当它需要结果时(当它必须将它们中的两个相加时)你会得到异常。

关于python - 修饰递归函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5860289/

相关文章:

python - 使用 python lib 从 FTP 获取大文件

c# - 你能写一个可以接受任意数量参数的 c# 装饰器函数吗?

python - 使用装饰器在类内部进行函数包装

python - Flask 应用程序的导入问题

python - 将参数解析为字典 argparse

python - python中的单例,闭包在装饰器内不起作用

python - functools.partial 以及它如何组成非关键字参数

clojure - 如何覆盖现有对象的方法?

python - 通过每个项目的两个第一个值优化列表列表中的频率

python - 如何在 vim 中关闭 Python 错误检查? (vim 终端 7.3、OS X 10.11 Yosemite)