在返回带有异常的递归python函数时遇到问题

时间:2016-03-05 14:54:01

标签: python

我有一个名为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)。 我也不确定如何更改装饰器以正确处理异常。

0 个答案:

没有答案