我有一个名为traced的装饰器,用于绘制将函数调用连接到其递归返回值的行。
class traced(object):
__nested=0
def __init__(self,f):
self.__f=f
self.__name__=f.__name__
def __call__(self,*args,**dargs):
l=0
arguments=""
for arg in args:
if(l!=0):
arguments+=", "
arguments +=str(arg)
l=l+1
items=dargs.iteritems()
for i in items:
if(l!=0):
arguments+=", "
arguments +=(str(i[0])+" = "+str(i[1]))
l=l+1
print("| "*type(self).__nested),
print(",- "+self.__name__+"("+arguments+")")
type(self).__nested+=1
try:
rv = self.__f(*args,**dargs)
type(self).__nested+=-1
print("| "*type(self).__nested),
print("`- "+repr(rv))
return rv
以下是使用此功能运行的示例:
>>> @traced
>>> def foo(a,b):
... if a==0: return b
... return foo(b=a-1,a=b-1)
...
>>> foo(4,5)
,- foo(4, 5)
| ,- foo(a=4, b=3)
| | ,- foo(a=2, b=3)
| | | ,- foo(a=2, b=1)
| | | | ,- foo(a=0, b=1)
| | | | `- 1
| | | `- 1
| | `- 1
| `- 1
`- 1
1
我需要它使用引发异常的函数正确运行,并提供了一个函数,我需要它才能运行,但我不知道如何编辑我的装饰器,因为我不能跟随函数的输出。 这是功能:
class ChangeException(Exception):
pass
@traced
def change_t(l,a):
if a==0:
return []
elif len(l)==0:
raise ChangeException()
elif l[0]>a:
return change_t(l[1:],a)
else:
try:
return [l[0]]+change_t(l,a-l[0])
except ChangeException:
return change_t(l[1:],a)
和提供的输出:
change_t([9, 7, 5], 44):
,- change_t([9, 7, 5], 44)
| ,- change_t([9, 7, 5], 35)
| | ,- change_t([9, 7, 5], 26)
| | | ,- change_t([9, 7, 5], 17)
| | | | ,- change_t([9, 7, 5], 8)
| | | | | ,- change_t([7, 5], 8)
| | | | | | ,- change_t([7, 5], 1)
| | | | | | | ,- change_t([5], 1)
| | | | | | | | ,- change_t([], 1)
| | | | | | ,- change_t([5], 8)
| | | | | | | ,- change_t([5], 3)
| | | | | | | | ,- change_t([], 3)
| | | | | | | ,- change_t([], 8)
| | | | ,- change_t([7, 5], 17)
| | | | | ,- change_t([7, 5], 10)
| | | | | | ,- change_t([7, 5], 3)
| | | | | | | ,- change_t([5], 3)
| | | | | | | | ,- change_t([], 3)
| | | | | | ,- change_t([5], 10)
| | | | | | | ,- change_t([5], 5)
| | | | | | | | ,- change_t([5], 0)
| | | | | | | | `- []
| | | | | | | `- [5]
| | | | | | `- [5, 5]
| | | | | `- [5, 5]
| | | | `- [7, 5, 5]
| | | `- [7, 5, 5]
| | `- [9, 7, 5, 5]
| `- [9, 9, 7, 5, 5]
`- [9, 9, 9, 7, 5, 5]
[9, 9, 9, 7, 5, 5]
我当前的输出:
>>> change_t([9, 7, 5], 44)
,- change_t([9, 7, 5], 44)
| ,- change_t([9, 7, 5], 35)
| | ,- change_t([9, 7, 5], 26)
| | | ,- change_t([9, 7, 5], 17)
| | | | ,- change_t([9, 7, 5], 8)
| | | | | ,- change_t([7, 5], 8)
| | | | | | ,- change_t([7, 5], 1)
| | | | | | | ,- change_t([5], 1)
| | | | | | | | ,- change_t([], 1)
| | | | | | | | | ,- change_t([5], 8)
| | | | | | | | | | ,- change_t([5], 3)
| | | | | | | | | | | ,- change_t([], 3)
| | | | | | | | | | | | ,- change_t([], 8)
| | | | | | | | | | | | | ,- change_t([7, 5], 17)
| | | | | | | | | | | | | | ,- change_t([7, 5], 10)
| | | | | | | | | | | | | | | ,- change_t([7, 5], 3)
| | | | | | | | | | | | | | | | ,- change_t([5], 3)
| | | | | | | | | | | | | | | | | ,- change_t([], 3)
| | | | | | | | | | | | | | | | | | ,- change_t([5], 10)
| | | | | | | | | | | | | | | | | | | ,- change_t([5], 5)
| | | | | | | | | | | | | | | | | | | | ,- change_t([5], 0)
| | | | | | | | | | | | | | | | | | | | `- []
| | | | | | | | | | | | | | | | | | | `- [5]
| | | | | | | | | | | | | | | | | | `- [5, 5]
| | | | | | | | | | | | | | | | | `- [5, 5]
| | | | | | | | | | | | | | | | `- [7, 5, 5]
| | | | | | | | | | | | | | | `- [7, 5, 5]
| | | | | | | | | | | | | | `- [9, 7, 5, 5]
| | | | | | | | | | | | | `- [9, 9, 7, 5, 5]
| | | | | | | | | | | | `- [9, 9, 9, 7, 5, 5]
[9, 9, 9, 7, 5, 5]
我理解change_t如何得到这个change_t([],3),但是不明白为什么下一个调用是change_t([],8)。 我也不确定如何更改装饰器以正确处理异常。