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

2024-06-28 20:01:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我在一个模块中有很多回调函数。它们都用第一个参数调用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, ..., ...)
    ...

代码上到处都是。比param2+param1更丑。在

在C/C++中,我只做宏< /p> ^{pr2}$

并开始在回调中使用S\F,而不是some_func。我可以用Python做什么?在


Tags: 模块函数fromimport参数defcallbackspace
3条回答
S_F = lambda a, b: some_func(param2+params1, param3, a, b)

请记住,param1param2和{}必须在lambda语句的作用域中可用,就像some_func。在

你可以以装饰师为基础:

import functools
from outer.space import some_func

def with_some(f):
    @functools.wraps(f)
    def wrapper(param1, param2, param3, *args):
        new_args = f(*args)
        return some_func(param1+param2, param3, *new_args)

    return wrapper

@with_some
def callback_A():
    return ()  # Will call some_func(param1 + param2, param3)

...

@with_some
def callback_B(param4):
    return param4,  # some_func(param1 + param2, param3, param4)

包装好的函数都有签名f(param1, param2, param3, *args)

您可以使用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)

编辑:

因为事先没有这些值,所以不能使用partial或{}。 您可能会想这样做:

^{pr2}$

但正如你所看到的,它不起作用。为什么?因为在定义函数时,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)

但这太难看了。在

如果只对函数使用位置参数,则可以执行更优雅的操作,例如:

>>> 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)

但在这一点上,你只是在重复另一篇文章,你失去了很多可读性。 如果您想在python中使用预处理功能,可以尝试Python Preprocessing,即使在您的情况下,我宁愿重复函数调用。在

相关问题 更多 >