o1i*_*ver 0 python recursion functional-programming composition function-composition
这个功能有什么问题?这似乎是一个范围错误(虽然我认为我通过将每个callable放在列表中而不是直接使用它来修复它).错误是达到最大递归深度(调用comp(inv,dbl,inc)时)...
注意:问题是:为什么它甚至会递归,而不是它达到最大深度的原因......
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)
Run Code Online (Sandbox Code Playgroud)
回溯(如果有帮助):
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
Run Code Online (Sandbox Code Playgroud)
您创建的lambda函数在composed
变量上构建一个闭包:
composed.append(lambda *args, **kwargs: func(composed[-1](*args,**kwargs)))
Run Code Online (Sandbox Code Playgroud)
这意味着composed[-1]
在创建 lambda函数时,但在调用它时,不会对其进行求值.效果是,这composed[-1]
将一次又一次递归地调用自己.
您可以通过使用辅助函数(具有自己的作用域)来创建lambda函数来解决此问题:
def comp2(f1, f2):
return lambda *args, **kwargs: f1(f2(*args, **kwargs))
...
for func in funcs:
composed.append(comp2(func, composed[-1]))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1177 次 |
最近记录: |