1.装饰器跟踪 【简单裴波那契数列】
def trace(f):
f.indent = 0
def g(x):
print(f"{' | ' * f.indent} |-- {f.__name__} {x}")
f.indent += 1
result = f(x)
print(f"{' | ' * f.indent} |-- Return {repr(result)}")
f.indent -= 1
return result
return g
@trace
def fib(n):
if n < 2:
return 1
else:
return fib(n - 1) + fib(n - 2)
print(fib(5))
输出:
|-- fib 5
| |-- fib 4
| | |-- fib 3
| | | |-- fib 2
| | | | |-- fib 1
| | | | | |-- Return 1
| | | | |-- fib 0
| | | | | |-- Return 1
| | | | |-- Return 2
| | | |-- fib 1
| | | | |-- Return 1
| | | |-- Return 3
| | |-- fib 2
| | | |-- fib 1
| | | | |-- Return 1
| | | |-- fib 0
| | | | |-- Return 1
| | | |-- Return 2
| | |-- Return 5
| |-- fib 3
| | |-- fib 2
| | | |-- fib 1
| | | | |-- Return 1
| | | |-- fib 0
| | | | |-- Return 1
| | | |-- Return 2
| | |-- fib 1
| | | |-- Return 1
| | |-- Return 3
| |-- Return 8
8
2.装饰器跟踪 【优化裴波那契数列】
def trace2(f):
cache = {}
f.indent = 0
def g(*args):
if args not in cache:
print(f"{' | ' * f.indent} |-- {f.__name__} {args}")
f.indent += 1
cache[args] = f(*args)
print(f"{' | ' * f.indent} |-- Return {repr(cache[args])}")
f.indent -= 1
return cache[args]
return g
@trace2
def fib2(n):
if n < 2:
return 1
else:
return fib2(n - 1) + fib2(n - 2)
%time fib2(20)
输出:
|-- fib2 (20,)
| |-- fib2 (19,)
| | |-- fib2 (18,)
| | | |-- fib2 (17,)
| | | | |-- fib2 (16,)
| | | | | |-- fib2 (15,)
| | | | | | |-- fib2 (14,)
| | | | | | | |-- fib2 (13,)
| | | | | | | | |-- fib2 (12,)
| | | | | | | | | |-- fib2 (11,)
| | | | | | | | | | |-- fib2 (10,)
| | | | | | | | | | | |-- fib2 (9,)
| | | | | | | | | | | | |-- fib2 (8,)
| | | | | | | | | | | | | |-- fib2 (7,)
| | | | | | | | | | | | | | |-- fib2 (6,)
| | | | | | | | | | | | | | | |-- fib2 (5,)
| | | | | | | | | | | | | | | | |-- fib2 (4,)
| | | | | | | | | | | | | | | | | |-- fib2 (3,)
| | | | | | | | | | | | | | | | | | |-- fib2 (2,)
| | | | | | | | | | | | | | | | | | | |-- fib2 (1,)
| | | | | | | | | | | | | | | | | | | | |-- Return 1
| | | | | | | | | | | | | | | | | | | |-- fib2 (0,)
| | | | | | | | | | | | | | | | | | | | |-- Return 1
| | | | | | | | | | | | | | | | | | | |-- Return 2
| | | | | | | | | | | | | | | | | | |-- Return 3
| | | | | | | | | | | | | | | | | |-- Return 5
| | | | | | | | | | | | | | | | |-- Return 8
| | | | | | | | | | | | | | | |-- Return 13
| | | | | | | | | | | | | | |-- Return 21
| | | | | | | | | | | | | |-- Return 34
| | | | | | | | | | | | |-- Return 55
| | | | | | | | | | | |-- Return 89
| | | | | | | | | | |-- Return 144
| | | | | | | | | |-- Return 233
| | | | | | | | |-- Return 377
| | | | | | | |-- Return 610
| | | | | | |-- Return 987
| | | | | |-- Return 1597
| | | | |-- Return 2584
| | | |-- Return 4181
| | |-- Return 6765
| |-- Return 10946
Wall time: 3 ms
10946
跟踪 【计算指数】
def trace(f):
f.indent = 0
def g(*args):
if args[1] % 2 == 0:
print(f"{' | ' * f.indent} +-- {args[0]} * {f.__name__} {args}")
else:
print(f"{' | ' * f.indent} +-- {f.__name__} {args}")
f.indent += 1
result = f(*args)
f.indent -= 1
print(f"{' | ' * f.indent} +-- Return {result}")
return result
return g
@trace
def fast_exp(x, n):
if n == 0:
return 1
elif n % 2 == 0:
return fast_exp(x * x, n / 2)
else:
return x * fast_exp(x, n - 1)
fast_exp(2, 10)
输出:
+-- 2 * fast_exp (2, 10)
| +-- fast_exp (4, 5.0)
| | +-- 4 * fast_exp (4, 4.0)
| | | +-- 16 * fast_exp (16, 2.0)
| | | | +-- fast_exp (256, 1.0)
| | | | | +-- 256 * fast_exp (256, 0.0)
| | | | | +-- Return 1
| | | | +-- Return 256
| | | +-- Return 256
| | +-- Return 256
| +-- Return 1024
+-- Return 1024