Как узнать, сколько аргументов нужно передать в указанную функцию - PullRequest
0 голосов
/ 06 марта 2019

Допустим, у меня есть две функции:

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 (в том же порядке)

возможно ли превратить это в одну функцию, не зная, сколько аргументов требуется для ссылочной функции?

Ответы [ 4 ]

1 голос
/ 06 марта 2019

Вы можете использовать атрибут объекта функции __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)
0 голосов
/ 06 марта 2019

Попробуйте это.

from inspect import signature

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

Это передает столько аргументов, которые ожидает функция, и игнорирует остальные.Если вы хотите использовать все аргументы позже, они находятся в списке args.

0 голосов
/ 06 марта 2019

Да. Если я вас правильно понимаю, вы хотите передать неопределенное количество аргументов в функцию?

Если это так, вы можете принять кортеж; такой, что функция может принять (a, b, c) или еще несколько аргументов. Кортежи похожи на списки, но не являются изменяемыми. Конечно, вам нужно убедиться, что введено правильное количество аргументов.

Ниже аргументы - это кортеж. Вы можете выполнить len (arguments), чтобы узнать, сколько аргументов было введено.

arguments=(bar, a, b)
foo(arguments)

def foo(my_tuple):
  result = arguments[0](arguments[1], arguments[2])
  return result
0 голосов
/ 06 марта 2019

Я думаю, вы, возможно, ищете оператора расширения *

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