【发布时间】:2016-05-07 07:20:25
【问题描述】:
Design of Computer Program 在 Udacity 上的一个讲座要求实现一个装饰器来跟踪递归:
from functools import update_wrapper
def decorator(d):
"Make function d a decorator: d wraps a function fn."
def _d(fn):
return update_wrapper(d(fn), fn)
update_wrapper(_d, d)
return _d
@decorator
def trace(f):
indent = ' '
def _f(*args):
signature = '%s(%s)' % (f.__name__, ', '.join(map(repr, args)))
print '%s--> %s' % (trace.level*indent, signature)
trace.level += 1
try:
# your code here
print '%s<-- %s == %s' % ((trace.level-1)*indent, signature, result)
finally:
# your code here
return # your code here
trace.level = 0
return _f
@trace
def fib(n):
if n == 0 or n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
fib(4)
我将代码填充到trace 函数中,它可以工作:
@decorator
def trace(f):
indent = ' '
def _f(*args):
signature = '%s(%s)' % (f.__name__, ', '.join(map(repr, args)))
print '%s--> %s' % (trace.level*indent, signature)
trace.level += 1
try:
result = f(*args)
print '%s<-- %s == %s' % ((trace.level-1)*indent, signature, result)
finally:
trace.level -= 1
return result
trace.level = 0
return _f
输出:
--> fib(4)
--> fib(3)
--> fib(2)
--> fib(1)
<-- fib(1) == 1
--> fib(0)
<-- fib(0) == 1
<-- fib(2) == 2
--> fib(1)
<-- fib(1) == 1
<-- fib(3) == 3
--> fib(2)
--> fib(1)
<-- fib(1) == 1
--> fib(0)
<-- fib(0) == 1
<-- fib(2) == 2
<-- fib(4) == 5
但很快我发现trace 可以不用try-finally:
@decorator
def trace(f):
indent = ' '
def _f(*args):
signature = '%s(%s)' % (f.__name__, ', '.join(map(repr, args)))
print '%s--> %s' % (trace.level*indent, signature)
trace.level += 1
result = f(*args)
print '%s<-- %s == %s' % ((trace.level-1)*indent, signature, result)
trace.level -= 1
return result
trace.level = 0
return _f
输出完全相同。
在这种情况下,我看不到 try-finally 的任何意义。谁能给我解释一下?
【问题讨论】:
-
尝试在
fib方法中引发异常。
标签: python exception-handling try-catch