【问题标题】:How to know how many arguments to pass to referenced function如何知道有多少参数传递给引用的函数
【发布时间】:2019-07-27 11:50:55
【问题描述】:

假设我有两个功能:

def foo1(bar, a, b, c):
  result = bar(a, b)
  return result

def foo2(bar, a, b, c):
  result = bar(a, b, c)
  return result

两种情况下的参数都是相同的,但取决于函数“bar”可能只需要 2 个,而另一个可能需要全部 3 个(以相同的顺序)

是否可以在不知道引用函数需要多少参数的情况下将其变成单个函数?

【问题讨论】:

  • 您想将所有提供的参数传递给函数吗?还是去掉多余的东西?
  • 另一种选择是使用try: bar(a, b, c) except TypeError: bar(a, b)
  • 我不想传递所有参数。 try/except 会起作用,但还有其他方法吗?
  • @dimakal 我链接的副本有很多方法。

标签: python python-3.x function reference arguments


【解决方案1】:

您可以使用函数对象的__code__.co_argcount 属性来获取它所期望的参数数量,您可以使用它来对参数列表进行切片:

def bar1(a, b):
    return b, a

def bar2(a, b, c):
    return c, b, a

def foo(bar, *args):
    return bar(*args[:bar.__code__.co_argcount])

print(foo(bar1, 1, 2, 3))
print(foo(bar2, 1, 2, 3))

这个输出:

(2, 1)
(3, 2, 1)

【讨论】:

  • 哪个更“pythonic”/更快? code.co_argcount 还是签名?我假设因为我不必导入任何东西,这将是一个更好的解决方案?
【解决方案2】:

试试这个。

from inspect import signature

def foo(bar, *args):
    arg_count = len(signature(bar).parameters)
    return bar(*args[:arg_count])

这会传递函数期望的许多参数,并忽略其余参数。如果您想稍后使用所有参数,它们在 args 列表中。

【讨论】:

    【解决方案3】:

    是的。如果我理解正确,您想将未指定数量的参数传递给函数吗?

    如果是这样,你可以接受一个元组;这样函数可以接受 (a, b, c) 或更多参数。元组类似于列表,但不可变。当然,您可以确保输入正确数量的参数。

    下面,arguments 是一个元组。 您可以执行 len(arguments) 来找出输入了多少个参数。

    arguments=(bar, a, b)
    foo(arguments)
    
    def foo(my_tuple):
      result = arguments[0](arguments[1], arguments[2])
      return result
    

    【讨论】:

      【解决方案4】:

      我认为您可能正在寻找 * 扩展运算符

      def foo(bar, *args):
        result = bar(*args)
        return result
      

      例如:

      In [1]: def foo(bar,*args): 
         ...:     return bar(*args) 
         ...:                                                                                                                                      
      
      In [2]: def f1(a): 
         ...:     return a 
         ...:                                                                                                                                      
      
      In [3]: def f2(a,b): 
         ...:     return a+b 
         ...:                                                                                                                                      
      
      In [4]: foo(f1,5)                                                                                                                            
      Out[4]: 5
      
      In [5]: foo(f2,5,6)                                                                                                                          
      Out[5]: 11
      
      In [6]: foo(f1,5,6)                                                                                                                          
      ---------------------------------------------------------------------------
      TypeError                                 Traceback (most recent call last)
      <ipython-input-6-5ca26cac7f4d> in <module>
      ----> 1 foo(f1,5,6)
      
      <ipython-input-1-fe8d4699f744> in foo(bar, *args)
            1 def foo(bar,*args):
      ----> 2     return bar(*args)
            3 
      
      TypeError: f1() takes 1 positional argument but 2 were given
      

      【讨论】:

      • 不幸的是,OP 只是在 cmets 中澄清他们不想传递所有参数。
      猜你喜欢
      • 2019-03-21
      • 2019-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-03
      • 2011-06-17
      • 1970-01-01
      相关资源
      最近更新 更多