将参数传递给具有命名参数的函数

Daf*_*der 3 python arguments python-3.x

如何将命名参数从另一个函数传递给一个函数?

在过去的 8 个小时里,我查看了包装器、argparse、Google。我错过了一些重要的事情。

def my_func(a='something', b='something_else'):
    # add a and b
    return something

def slave(func, args):
    result = func(args)
    return result

slave_work = {my_func, (a=50, b=90)}

print (slave(slave_work)
Run Code Online (Sandbox Code Playgroud)

应该输出140. 我怎样才能做到这一点?

Tom*_*koo 6

您现在所做的只是将一组slave作为单个参数传递。所以你可能缺少一个TypeError位置论证。

你可能想把你的变成slave_work一个字典(现在它是一个集合),然后它看起来像:

slave_work = {'func': my_func, 'args': {'a': 50, 'b': 90}}
Run Code Online (Sandbox Code Playgroud)

现在你可以通过执行以下操作来解压字典:

print(slave(**slave_work))
Run Code Online (Sandbox Code Playgroud)

这或多或少相当于执行以下操作:

print(slave(func=slave_work['func'], args=slave_work['args'])
Run Code Online (Sandbox Code Playgroud)

然后在你的slave函数内部相应地更改为:

result = func(**args)
Run Code Online (Sandbox Code Playgroud)

另一种选择是使用列表(或本例中的元组)解包。所以你slave_work也可以是:

slave_work = {'func': my_func, 'args': (50, 90)}
Run Code Online (Sandbox Code Playgroud)

然后你的调用slave将是相同的,但内部 slave更改为:

result = func(*args)
Run Code Online (Sandbox Code Playgroud)

不同之处在于,这将根据参数的位置而不是名称来解压缩参数。


Mis*_*agi 5

Python 允许将可迭代对象解压/打包到位置参数以及映射到关键字参数。语法分别为*arguments**keywords

>>> def my_func(a, b):
...     return a - b
...
>>> args = [2, 1]   # iterable for positional arguments
>>> my_func(*args)  # unpack iterable
1
>>> kwargs = {'b': 1, 'a': 2}  # mapping for keyword arguments
>>> my_func(**kwargs)          # unpack mapping
1
Run Code Online (Sandbox Code Playgroud)

您甚至可以组合两种形式的可变参数 - 例如my_func(*args, **kwargs)


要创建调用另一个函数的包装函数,您可以使用它:

  • 显式传入迭代/映射:

    # take regular arguments...
    def slave(func, args, kwargs):
        # ...and unpack them
        result = func(*args, **kwargs)
        return result
    
    # explicit iterable [1] and mapping {'b': 2}
    print(slave(my_func, [1], {'b': 2}))
    # from existing args/kwargs
    args, kwargs = [1], {'b': 2}
    print(slave(my_func, args, kwargs))
    
    Run Code Online (Sandbox Code Playgroud)

    显式迭代/映射对于脚本接口来说更简单,即当argskwargsslave(func, args, kwargs). 它们对于手动使用来说相当麻烦,即当您调用slave(func, [1], {'b': 2}).

  • 转换传入的参数:

    # take variadic arguments...
    def slave(func, *args, **kwargs):
        # ...and pass them on
        result = func(*args, **kwargs)
        return result
    
    # explicit iterable [1] and mapping {'b': 2}
    print(slave(my_func, 1, b=2))
    # from existing args/kwargs
    args, kwargs = [1], {'b': 2}
    print(slave(my_func, *args, **kwargs))
    
    Run Code Online (Sandbox Code Playgroud)

    隐式迭代/映射对于手动使用来说更简单,即当您调用slave(func, 1, b=2). 对于脚本化接口来说,它们的成本很高,即当您有args/kwargs并且必须将它们相关地解压到slave(func, *args, **kwargs).