Ein Vortrag von Design of Computer Program auf Udacity bitten, einen Dekorateur zu implementieren Rekursion verfolgen:Unnötige try-finally
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)
ich den Code in trace
Funktion ausfüllen und es funktioniert:
@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
Ausgang:
--> 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
Aber bald finde ich heraus, dass trace
könnte gehen ohne 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
Mit genau dem gleichen Ausgang.
Ich sehe keinen Punkt von try-finally
in diesem Fall. Kann mir das jemand erklären?
versuchen, eine Ausnahme in der 'fib' Methode zu erhöhen. – totoro