问题描述
这个函数有什么问题?这似乎是一个范围错误(尽管我认为我已经通过将每个可调用对象放在列表中,而不是直接使用它)解决了这个问题。错误是最大递归深度达到了(当调用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函数组合(最大递归深度错误,作用域?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!