Программно определяющее количество параметров, которые требуется функции – Python

Я создавал простую утилиту командной строки и использовал словарь как своего рода оператор case с ключевыми словами, ссылающимися на их соответствующую функцию. Все функции имеют различное количество аргументов, необходимых в настоящее время, чтобы проверить, правильно ли пользователь ввел правильное количество аргументов, необходимых для каждой функции. Я поместил требуемую сумму в оператор словаря в форме {Keyword:(FunctionName, AmountofArguments)} .

Эта текущая настройка работает отлично, но я просто задавался вопросом в интересах самосовершенствования, если бы был способ определить необходимое количество аргументов в функции, и мои попытки Google вернулись до сих пор ничего не ценного, но я вижу, как args и kwargs мог вкрутить такую ​​команду из-за неограниченного количества аргументов, которые они позволяют.

6 Solutions collect form web for “Программно определяющее количество параметров, которые требуется функции – Python”

inspect.getargspec () :

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

То, что вы хотите, вообще невозможно, из-за использования varargs и kwargs, но inspect.getargspec (Python 2.x) и inspect.getfullargspec (Python 3.x) приближаются.

  • Python 2.x:

     >>> import inspect >>> def add(a, b=0): ... return a + b ... >>> inspect.getargspec(add) (['a', 'b'], None, None, (0,)) >>> len(inspect.getargspec(add)[0]) 2 
  • Python 3.x:

     >>> import inspect >>> def add(a, b=0): ... return a + b ... >>> inspect.getfullargspec(add) FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(0,), kwonlyargs=[], kwonlydefaults=None, annotations={}) >>> len(inspect.getfullargspec(add).args) 2 

В Python 3 используйте someMethod.__code__.co_argcount

(поскольку someMethod.func_code.co_argcount больше не работает)

Это уже ответили, но без модуля проверки вы также можете использовать someMethod.func_code.co_argcount

Сделайте каждую команду классом, полученным из абстрактной базы, определяющей общую структуру команды. Как можно больше, определение свойств команд должно быть помещено в переменные класса с методами, определенными в базовом классе, обрабатывающим эти данные.

Зарегистрируйте каждый из этих подклассов с заводским классом. Этот заводский класс получает список аргументов, который определяет, какую команду выполнить, создав соответствующий класс подкласс команды.

Проверка аргументов обрабатывается самими подклассами команд, используя правильно определенные общие методы из базового класса команды.

Таким образом, вам не нужно многократно кодировать один и тот же материал, и нет необходимости эмулировать оператор switch. Он также упрощает расширение и добавление команд, поскольку вы можете просто добавить и зарегистрировать новый класс. Больше ничего не изменится.

Отличный вопрос. У меня просто была проблема, что я хотел написать функцию, которая принимает аргумент обратного вызова. В зависимости от количества аргументов этого обратного вызова его нужно вызывать по-разному.

Я начал с ответа Гимеля, затем расширился, чтобы иметь дело со встроенными, которые плохо реагируют на модуль inspect ( raise TypeError ).

Итак, вот код, чтобы проверить, ожидает ли функция только один аргумент:

 def func_has_one_arg_only(func, typical_argument=None, ignore_varargs=False): """True if given func expects only one argument Example (testbench): assert not func_has_one_arg_only(dict.__getitem__), 'builtin 2 args' assert func_has_one_arg_only(lambda k: k), 'lambda 1 arg' assert not func_has_one_arg_only(lambda k,x: k), 'lambda 2 args' assert not func_has_one_arg_only(lambda *a: k), 'lambda *a' assert not func_has_one_arg_only(lambda **a: k), 'lambda **a' assert not func_has_one_arg_only(lambda k,**a: k), 'lambda k,**a' assert not func_has_one_arg_only(lambda k,*a: k), 'lambda k,*a' assert func_has_one_arg_only(lambda k: k, ignore_varargs=True), 'lambda 1 arg' assert not func_has_one_arg_only(lambda k,x: k, ignore_varargs=True), 'lambda 2 args' assert not func_has_one_arg_only(lambda *a: k, ignore_varargs=True), 'lambda *a' assert not func_has_one_arg_only(lambda **a: k, ignore_varargs=True), 'lambda **a' assert func_has_one_arg_only(lambda k,**a: k, ignore_varargs=True), 'lambda k,**a' assert func_has_one_arg_only(lambda k,*a: k, ignore_varargs=True), 'lambda k,*a' """ try: import inspect argspec = inspect.getargspec(func) except TypeError: # built-in c-code (eg dict.__getitem__) try: func(typical_argument) except TypeError: return False else: return True else: if not ignore_varargs: if argspec.varargs or argspec.keywords: return False if 1 == len(argspec.args): return True return False raise RuntimeError('This line should not be reached') 

Вы можете управлять поведением, связанным с параметрами varargs *args и **kwargs с параметром ignore_varargs .

typical_argument параметр_аргумента – это kludge: Если inspect не работает, например, на вышеупомянутых встроенных, мы просто пытаемся вызвать функцию с одним аргументом и посмотреть, что произойдет.

Проблема с этим подходом заключается в том, что существует несколько причин для raise TypeError : либо используется неправильное количество аргументов, либо используется неправильный тип аргументов. Предоставляя пользователю предоставить typical_argument я пытаюсь обойти эту проблему.

Это не приятно. Но это может помочь людям, которые имеют один и тот же вопрос, а также сталкиваются с тем, что inspect не может проверять реализации C-кодированных функций. Может быть, у людей есть лучшее предложение?

  • Основная функция Python не работает
  • Как я могу получить исходный код функции Python?
  • regexp автоматически запускается на вход функции?
  • Запустите функцию PowerShell из скрипта Python
  • Python: как остановить функцию?
  • Python в операторе не работает
  • Возврат функции Python
  • Как python реализует взаимную рекурсию?
  • Python - лучший язык программирования в мире.