【问题标题】:Passing arguments to a function with named arguments将参数传递给具有命名参数的函数
【发布时间】:2019-12-19 22:26:35
【问题描述】:

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

在过去的 8 个小时里,我一直在研究 wrappers、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)

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

【问题讨论】:

    标签: python python-3.x arguments


    【解决方案1】:

    您现在所做的只是将一个集合作为单个参数传递给slave。因此,您可能会在缺少位置参数时收到TypeError

    您可能希望将您的 slave_work 更改为 dict(现在它是一个集合),然后它看起来像:

    slave_work = {'func': my_func, 'args': {'a': 50, 'b': 90}}
    

    现在您可以通过以下方式解压字典:

    print(slave(**slave_work))
    

    这或多或少等同于做:

    print(slave(func=slave_work['func'], args=slave_work['args'])
    

    然后在您的slave 函数中相应更改为:

    result = func(**args)
    

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

    slave_work = {'func': my_func, 'args': (50, 90)}
    

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

    result = func(*args)
    

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

    【讨论】:

      【解决方案2】:

      Python 允许 un/pack 可迭代到位置参数和映射到关键字参数。语法分别为*arguments and **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
      

      您甚至可以结合两种形式的可变参数 - 例如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))
        

        显式可迭代/映射对于脚本接口更简单,即当您在slave(func, args, kwargs) 中使用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))
        

        隐式迭代/映射更易于手动使用,即当您调用 slave(func, 1, b=2) 时。它们对于脚本接口来说成本很高,即当你有 args/kwargs 并且必须在 slave(func, *args, **kwargs) 中相关地解压它们时。

      【讨论】:

      • 我赢得了另一个答案,因为它有效并且我很容易理解它。话虽如此,在重新阅读您的答案后,您会给出两种做事方式。这也太棒了:)
      猜你喜欢
      • 2014-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-03
      相关资源
      最近更新 更多