从接受任何参数的函数返回 functools.partial

Returning a functools.partial from a function accepting any arguments

我需要创建一个模拟方法来存储传递给它的任何参数,这样我以后就可以断言它被正确调用了。为此,我需要从模拟对象存储函数创建函数,这样我就可以 return 除了存储所有参数之外的任何我想要的东西。我正在尝试做的 MWE 看起来像这样:

import functools
f1 = lambda test, *a, **b: print(a, b, test)
f2 = functools.partial(f1, test=42)
f2(2,3,a=4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: <lambda>() got multiple values for argument 'test'

是否可以让它工作?本质上我需要 f2 来接受任意数量的位置或 keyword_arguments,但是已经将参数 test 定义为 f1.

的输入

我想要上面的调用 f2 打印:

(2, 3) {'a': 4} 42

或类似的,重要的是 test 可以在 f1 中使用,但不必为 f2.[=21= 预定义 set/is ]

你可以做到

import functools
f1 = lambda test, *a, **b: print(a, b, test)
f2 = functools.partial(f1, 42)
f2(2, 3, a=4)

输出:

(2, 3) {'a': 4} 42

请注意,在这种情况下使用 lambda 不符合 PEP8 recommendations。改为使用常规函数:

Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier:

# Correct: def f(x): return 2*x
 
# Wrong: f = lambda x: 2*x

The first form means that the name of the resulting function object is specifically 'f' instead of the generic ''. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)

不使用部分也能工作:

f1 = lambda test, *a, **b: print(a, b, test)
f2 = lambda *args, **kwargs: f1(42, *args, **kwargs)
f2(2,3,a=4)

# (2, 3) {'a': 4} 42