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 做什么?
您可以使用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)
编辑:
由于您事先没有这些值,因此无法使用partial
or 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,尽管在您的情况下,我宁愿只是重复函数调用。