是否有接受元组的函数的语法糖?

时间:2018-01-12 21:51:42

标签: python

假设我有一个带有两个参数的函数并对它们执行一些计算:

def add(a, b):
    return a + b

我想通过多处理库调用此函数,该库只能处理具有单个参数的函数。所以,我改变函数将其参数改为单个元组:

def add2(ab):
    a, b = ab
    return a + b

然而,这对我来说似乎很笨拙。变量基本上需要定义(并记录)两次。如果我使用的是lambda函数,我可以编写以下内容,它将正确接受元组:

add3 = lambda (a, b): a + b

不幸的是,我的函数不足以实现作为lambda函数。在python中是否有任何类型的语法糖功能允许我编写一个接受元组的命名函数,但将该元组的每个组件视为一个单独的命名参数?我尝试搜索解决方案的尝试主要是对*args运算符的引用,但这不适用于此,因为我不控制调用该函数的站点。

以下是如何调用函数的示例。请注意,它是通过多处理库调用的,所以我不能传递多个参数:

import multiprocessing
pool = multiprocessing.Pool(processes=4)
for result in pool.imap_unordered(add, [(1,2),(3,4)]):
    print(result)

欢迎使用python 2.7或3.x的答案。

4 个答案:

答案 0 :(得分:4)

最好不要改变原来的功能界面,使其更少Pythonic。  在Python 2中,编写一个包装函数以用于多处理。

def _add(args):
    return add(*args)

在Python 3中,只需使用Pool.starmap

>>> def add(a, b):
...     return a + b
... 
>>> p = Pool()
>>> list(p.starmap(add, [(1, 2), ('hello', ' world')]))
[3, 'hello world']

答案 1 :(得分:0)

如果您担心重复自己(ab出现次数过多),只需为传入的元组指定一个非描述性名称。

def add(t):
    a, b = t
    return a + b

或者,在您的特定情况下,您可以通过索引元组来完全避免ab

def add(addends):
    return addends[0] + addends[1]

作为替代方法,您可以包装函数,以便源代码具有熟悉的参数格式,但正在使用的函数具有元组参数:

def tupleize(func):
    def wrapper(tup):
        return func(*tup)
    return wrapper

@tupleize
def add(a, b):
    return a+b

t = 1, 2
assert(add(t) == 3)

答案 2 :(得分:-1)

当我写这个问题时,我找到了在Python 2.7中实现它的方法:

def add4((a, b)):
    return a + b

然而,显然这在Python 3中不再有效,因此关于Python 3的其他答案仍然有用。

答案 3 :(得分:-1)

您可以使用装饰器扩展多处理库函数以获取多个参数,执行您想要的任何操作,然后使用单个参数调用它。

例如,一个简单的装饰器,它接受任意数量的参数,将它们加在一起,然后用total作为单个参数调用原始函数:

import 3rdpartylib

def sum_args(func):
    def inner(*args):
      return func(sum(args))
    return inner

# Replace imported function with decorated version
3rdpartylib = sum_args(3rdpartylib)

# Decorate your own libraries
@sum_args
def my_own_lib(number):
    print("A:", number)

3rdpartylib(1,2,3,4)
my_own_lib(5,10,15)

主要优点是你可以使用相同的装饰器函数来装饰/替换任意数量的方法,以达到同样的效果。