Как найти количество аргументов функции Python?

Как найти количество аргументов функции Python? Мне нужно знать, сколько у него обычных аргументов и сколько именованных аргументов.

Пример:

def someMethod(self, arg1, kwarg1=None):
    pass

Этот метод имеет 2 аргумента и 1 именованный аргумент.

Ответ 1

Ранее принятый ответ был устарел с Python 3.0. Вместо использования inspect.getargspec вы должны выбрать класс Signature, который заменил бы его.

Создание подписи для функции легко с помощью функции Signature:

from inspect import signature

def someMethod(self, arg1, kwarg1=None):
    pass

sig = signature(someMethod)

Теперь вы можете быстро просмотреть его параметры с помощью str ing:

str(sig)  # returns: '(self, arg1, kwarg1=None)'

или вы также можете получить сопоставление имен атрибутов с объектами параметров через sig.parameters.

params = sig.parameters 
print(params['kwarg1']) # prints: kwarg1=20

Кроме того, вы можете вызвать len на sig.parameters, чтобы увидеть количество аргументов, необходимых этой функции:

print(len(params))  # 3

Каждая запись в отображении params фактически представляет собой объект Parameter, который имеет дополнительные атрибуты, облегчающие вашу жизнь. Например, захват параметра и просмотр его значения по умолчанию теперь легко выполняются с помощью:

kwarg1 = params['kwarg1']
kwarg1.default # returns: None

аналогично для остальных объектов, содержащихся в parameters.


Что касается пользователей Python 2.x, а inspect.getargspec не устарел, язык скоро будет:-). Класс Signature недоступен в серии 2.x и не будет. Поэтому вам все равно нужно работать с inspect.getargspec.

Что касается перехода между Python 2 и 3, если у вас есть код, который полагается на интерфейс getargspec в Python 2 и переключение на Signature в 3 слишком сложно, у вас есть ценная опция использования inspect.getfullargspec. Он предлагает аналогичный интерфейс getargspec (один вызываемый аргумент), чтобы захватить аргументы функции, а также обрабатывать некоторые дополнительные случаи, когда getargspec не выполняет:

from inspect import getfullargspec

def someMethod(self, arg1, kwarg1=None):
    pass

args = getfullargspec(someMethod)

Как и в случае с getargspec, getfullargspec возвращает a NamedTuple, который содержит аргументы.

print(args)
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})

Ответ 3

someMethod.func_code.co_argcount

или, если текущее имя функции не определено:

import sys

sys._getframe().func_code.co_argcount

Ответ 4

inspect.getargspec()

Получить имена и значения по умолчанию аргументов функций. Возвращается кортеж из четырех вещей: (args, varargs, varkw, defaults). args - список имен аргументов (он может содержать вложенные списки). varargs и varkw - это имена аргументов * и ** или None. defaults - кортеж значений аргументов по умолчанию или None, если нет аргументов по умолчанию; если этот кортеж имеет n элементов, они соответствуют последним n элементам, перечисленным в args.

Изменено в версии 2.6: Возвращает именованный кортеж ArgSpec (args, varargs, keywords, defaults).

См. can-you-list-the-keyword-arguments-a-python-function-receives.

Ответ 5

Добавляя к вышесказанному, я также видел, что большая часть времени help() действительно помогает

Например, он дает всю информацию о аргументах, которые он принимает.

help(<method>)

дает ниже

method(self, **kwargs) method of apiclient.discovery.Resource instance
Retrieves a report which is a collection of properties / statistics for a specific customer.

Args:
  date: string, Represents the date in yyyy-mm-dd format for which the data is to be fetched. (required)
  pageToken: string, Token to specify next page.
  parameters: string, Represents the application name, parameter name pairs to fetch in csv as app_name1:param_name1, app_name2:param_name2.

Returns:
  An object of the form:

    { # JSON template for a collection of usage reports.
    "nextPageToken": "A String", # Token for retrieving the next page
    "kind": "admin#reports#usageReports", # Th

Ответ 6

Хорошие новости для людей, которые хотят сделать это переносимым способом между Python 2 и Python 3. 6+: используйте inspect.getfullargspec(). Он работает как в Python 2.x, так и в 3. 6+

Как указывали Джим Фасаракис Хиллиард и другие, раньше это было так:
1. В Python 2.x: используйте inspect.getargspec()
2. В Python 3.x: используйте подпись, так как getargspec() и getfullargspec() устарели.

Однако, начиная с Python 3.6 (по многочисленным просьбам?), Ситуация изменилась к лучшему:

Со страницы документации Python 3:

inspect.getfullargspec(FUNC)

Изменено в версии 3.6: этот метод ранее был задокументирован как устаревший в пользу signature() в Python 3.5, но это решение было отменено, чтобы восстановить явно поддерживаемый стандартный интерфейс для кода Python 2/3 с одним исходным кодом, мигрирующего из устаревший API getargspec().

Ответ 7

inspect.getargspec() для удовлетворения ваших потребностей

from inspect import getargspec

def func(a, b):
    pass
print len(getargspec(func).args)

Ответ 8

Как показывают другие ответы, getargspec работает хорошо, пока запрашиваемая вещь на самом деле является функцией. Он не работает для встроенных функций, таких как open, len и т.д., И генерирует исключение в таких случаях:

TypeError: <built-in function open> is not a Python function

Следующая функция (вдохновленная этим ответом) демонстрирует обходной путь. Он возвращает количество ожидаемых аргументов f:

from inspect import isfunction, getargspec
def num_args(f):
  if isfunction(f):
    return len(getargspec(f).args)
  else:
    spec = f.__doc__.split('\n')[0]
    args = spec[spec.find('(')+1:spec.find(')')]
    return args.count(',')+1 if args else 0

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