Python函数组合(最大递归深度错误,作用域?) [英] Python function composition (max recursion depth error, scope?)

查看:130
本文介绍了Python函数组合(最大递归深度错误,作用域?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个函数有什么问题?这似乎是一个范围错误(尽管我认为我已经通过将每个可调用对象放在列表中,而不是直接使用它)解决了这个问题。错误是最大递归深度达到了(当调用comp(inv,dbl,inc)时)...

注意:问题是:为什么它是递归的,而不是为什么它达到了最大深度...

pre $ def $(* funcs)
如果len(funcs)在( 0,1):
增加ValueError('至少需要两个函数组合')
#获取大多数内部函数
合成= []
print(appending func 1 )
compos.append(funcs [-1])$ ​​b $ b#弹出最后和反向
funcs = funcs [: - 1] [:: - 1]
i = 1
for func in funcs:
i + = 1
print(appending func%s%i)
composed.append(lambda * args,** kwargs:func(composed [ 1](* args,** kwargs)))
返回合成[-1]

def inc(x):
print(inc用%s调用 x)
return x + 1
def dbl(x):
print(dbl调用%s%x)
return x * 2
def inv (x):
print(inv调用%s%x)
return x *( - 1)

if __name__ =='__main__':
comp(inv,dbl,inc)(2)

回溯(如果有帮助):

 追加func 1 
追加func 2
appending func 3
Traceback(最近一次调用的最后一个):
在< module>文件中的第31行comp.py
comp(inv,dbl,inc)(2)
在< lambda>文件中,将第17行的comp.py
composed.append(lambda * args,** kwargs:func(composed [-1](* args,** kwargs)))
文件comp.py,第17行,放在<拉姆达>
composed.append(lambda * args,** kwargs:func(composed [-1](* args,** kwargs)))
文件comp.py,第17行,放在<拉姆达>
composed.append(lambda * args,** kwargs:func(composed [-1](* args,** kwargs)))
(...)
Filecomp。 py,第17行,在< lambda>
compiled.append(lambda * args,** kwargs:func(composed [-1](* args,** kwargs)))
RuntimeError:调用Python对象时超出最大递归深度


解决方案

您创建的lambda函数通过<$ c

$ comp $ comp $(lambda * args,** kwargs:func) (由[-1](* args,** kwargs)))

这意味着<$当创建 lambda函数时,当您调用时,不会评估c $ c> composed [-1] 。结果是,组成的[-1] 会自动递归地调用自己。



你可以解决这个问题通过使用一个帮助器函数(用它自己的作用域)来创建lambda函数:

pre $ code> def comp2(f1,f2) :
返回lambda * args,** kwargs:f1(f2(* args,** kwargs))

...
func中的func:
compos.append(comp2(func,composed [-1]))


What is wrong with this function? It seems like a scope error (although I thought I had fixed that by placing each callable in the list, instead of using it directly). Error is max recursion depth reached (when calling comp(inv,dbl,inc))...

Note: the question is: why is it even recursing, not why it's reaching the max depth...

def comp(*funcs):
    if len(funcs) in (0,1):
        raise ValueError('need at least two functions to compose')
    # get most inner function
    composed = []
    print("appending func 1")
    composed.append(funcs[-1])
    # pop last and reverse
    funcs = funcs[:-1][::-1]
    i = 1
    for func in funcs:
        i += 1
        print("appending func %s" % i)
        composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))
    return composed[-1]

def inc(x):
    print("inc called with %s" % x)
    return x+1
def dbl(x):
    print("dbl called with %s" % x)
    return x*2
def inv(x):
    print("inv called with %s" % x)
    return x*(-1)

if __name__ == '__main__':
    comp(inv,dbl,inc)(2)

Traceback (if it helps):

appending func 1
appending func 2
appending func 3
Traceback (most recent call last):
  File "comp.py", line 31, in <module>
    comp(inv,dbl,inc)(2)
  File "comp.py", line 17, in <lambda>
    composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))
  File "comp.py", line 17, in <lambda>
    composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))
  File "comp.py", line 17, in <lambda>
    composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))
  (...)
  File "comp.py", line 17, in <lambda>
    composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))
RuntimeError: maximum recursion depth exceeded while calling a Python object

解决方案

The lambda function you create builds a closure over the composed variable:

composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))

This means that composed[-1] isn't evaluated when you create the lambda function, but when you call it. The effect is, that composed[-1] will be calling itself recursively again and again.

You can solve this problem by using a helper function (with its own scope) to create the lambda functions:

def comp2(f1, f2):
    return lambda *args, **kwargs: f1(f2(*args, **kwargs))

...
for func in funcs:
     composed.append(comp2(func, composed[-1]))

这篇关于Python函数组合(最大递归深度错误,作用域?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆