一种自动将参数传递给函数的方法?

Ale*_*lov 5 python parameter-passing

我在一个模块中有一堆回调函数。他们都some_func()用第一个参数调用,比如说,几个参数总是相同的,并且来自它们自己的参数,而其他参数则不同。像这样:

from outer.space import some_func
def callback_A(param1, param2, param3):
    ...
    some_func(param2+param1, param3, ..., ...)
    ...

def callback_B(param1, param2, param3, param4):
    ...
    some_func(param2+param1, param3, ..., ...)
    ...
Run Code Online (Sandbox Code Playgroud)

这在代码中无处不在。而且比 param2+param1 更丑陋。

在 C/C++ 中,我只是做一个宏

#define    S_F(a,b)    some_func(param2+param1, param3, a, b)
Run Code Online (Sandbox Code Playgroud)

并开始在回调中使用 S_F 而不是some_func. 我可以用 Python 做什么?

Bak*_*riu 3

您可以使用functools.partial

>>> from functools import partial
>>> def my_function(a,b,c,d,e):
...     print (a,b,c,d,e)
... 
>>> func_with_defaults = partial(my_function, 1, 2, e=5)
>>> func_with_defaults(3, 4)
(1, 2, 3, 4, 5)
Run Code Online (Sandbox Code Playgroud)

编辑:

由于您事先没有这些值,因此无法使用partialor lambda。您可能会想这样做:

>>> A = lambda x: x + y
>>> def do_something(y):
...     return A(2)    # hope it uses the `y` parameter...
... 
>>> do_something(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in do_something
  File "<stdin>", line 1, in <lambda>
NameError: global name 'y' is not defined
Run Code Online (Sandbox Code Playgroud)

但正如你所看到的,它不起作用。为什么?因为当你定义一个函数时,python 会保存你定义它的范围并使用它来解析global/nonlocal变量。

如果您有权访问,some_func则可以通过使用“破解”解释器堆栈来完成您想要的操作,inspect但这不是一个健壮或优雅的事情,所以不要这样做

对于你的情况,我要做的就是简单地重写该声明。

如果你真的想避免这种情况,你可以尝试使用以下方法exec

>>> def some_function(a,b,c):
...     print(a,b,c)
... 
>>> code = 'some_function(a+b,c,%s)'
>>> 
>>> def func_one(a,b, c):
...     exec code % 1
... 
>>> def func_two(a,b,c):
...     exec code % 2
... 
>>> func_one(1,2,3)
(3, 3, 1)
>>> func_two(1,2,3)
(3, 3, 2)
Run Code Online (Sandbox Code Playgroud)

但这很丑陋

如果您仅在函数中使用位置参数,您可以做一些更优雅的事情,例如:

>>> def compute_values(a,b,c):
...     return (a+b, c)
... 
>>> def func_one(a,b,c):
...     some_function(*(compute_values(a,b,c) + (1,)))
... 
>>> def func_two(a,b,c):
...     some_function(*(compute_values(a,b,c) + (2,)))
... 
>>> func_one(1,2,3)
(3, 3, 1)
>>> func_two(1,2,3)
(3, 3, 2)
Run Code Online (Sandbox Code Playgroud)

但此时你只是在重复不同的文本,并且失去了很多可读性。如果您想在 python 中具有预处理功能,您可以尝试Python Preprocessing,尽管在您的情况下,我宁愿只是重复函数调用。