I have the following minimal example that reproduces the issue:
def f1(a, b):
print(1)
return a + b
def f2(a, b):
print(2)
return a * b
funcs = f1, f2
_funcs = []
for func in funcs:
def _func(x):
return func(*x)
_func.__name__ = func.__name__
_funcs.append(_func)
funcs = _funcs
for func in funcs:
print(func([2, 3]))
This throws a TypeErro
:
TypeError: _func() takes 1 positional argument but 2 were given
with the following traceback:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-93-e24e67b5e525> in <module>()
22
23 for func in funcs:
---> 24 print(func([2, 3]))
<ipython-input-93-e24e67b5e525> in _func(x)
14
15 def _func(x):
---> 16 return func(*x)
17
18 _func.__name__ = func.__name__
TypeError: _func() takes 1 positional argument but 2 were given
I am not sure why as it seems to me that _func()
is always called with a single argument.
I suspect what I want to do would be done with functools
, but still I fail to see why the above code works this way. Any hint?
You are closing over the free-variable
func
when you define:However, in your loop, you re-using this name,
So
func
now refers to the single-argument functions you defined, even inside_func
! So of course, when that function callsfunc(*x)
it's actually recursively calling itself. Use a different name:Or better yet, don't rely on a free-variable you don't intend to be free:
And use that: