Как я могу найти количество аргументов функции Python?
Как я могу найти количество аргументов функции Python? Мне нужно знать, сколько у него нормальных аргументов и сколько именованных аргументов.
Пример:
def someMethod(self, arg1, kwarg1=None):
pass
Этот метод имеет 2 аргумента и 1 именованный аргумент.
14 ответов
Ранее принятый ответ устарел с Python 3.0
, Вместо того, чтобы использовать inspect.getargspec
теперь вы должны выбрать Signature
класс, который заменил его.
Создать подпись для функции легко с помощью signature
функция:
from inspect import signature
def someMethod(self, arg1, kwarg1=None):
pass
sig = signature(someMethod)
Теперь вы можете быстро просмотреть его параметры с помощью str
Инг это:
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
возвращает NamedTuple
который содержит аргументы.
print(args)
FullArgSpec(args=['self', 'arg1', 'kwarg1'], varargs=None, varkw=None, defaults=(None,), kwonlyargs=[], kwonlydefaults=None, annotations={})
import inspect
inspect.getargspec(someMethod)
см. модуль проверки
func.__code__.co_argcount
дает вам количество любых аргументов ДО *args
func.__kwdefaults__
дает вам dict ключевых аргументов ПОСЛЕ *args
func.__code__.co_kwonlyargcount
равно len(func.__kwdefaults__)
func.__defaults__
дает вам значения необязательных аргументов, которые появляются перед *args
Вот простая иллюстрация:
>>> def a(b, c, d, e, f=1, g=3, h=None, *i, j=2, k=3, **L):
pass
>>> a.__code__.co_argcount
7
>>> a.__defaults__
(1, 3, None)
>>> len(a.__defaults__)
3
>>>
>>>
>>> a.__kwdefaults__
{'j': 2, 'k': 3}
>>> len(a.__kwdefaults__)
2
>>> a.__code__.co_kwonlyargcount
2
someMethod.func_code.co_argcount
или, если текущее имя функции не определено:
import sys
sys._getframe().func_code.co_argcount
Получить имена и значения по умолчанию аргументов функции. Возвращается кортеж из четырех вещей: (args, varargs, varkw, defaults). args - это список имен аргументов (он может содержать вложенные списки). varargs и varkw - это имена аргументов * и ** или None. defaults - это кортеж значений аргументов по умолчанию или None, если аргументов по умолчанию нет; если этот кортеж имеет n элементов, они соответствуют последним n элементам, перечисленным в аргументах.
Изменено в версии 2.6: Возвращает именованный кортеж ArgSpec(args, varargs, ключевые слова, значения по умолчанию).
См. /questions/9056422/mozhete-li-vyi-perechislit-klyuchevyie-argumentyi-kotoryie-poluchaet-funktsiya.
Помимо вышесказанного, я также видел, что в большинстве случаев функция 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
Вы получаете количество аргументов:
function.__code__.co_argcount ## 2
И имена или аргументы:
function.__code__.co_varnames ## ('a', 'b')
Хорошие новости для людей, которые хотят сделать это портативным способом между Python 2 и Python 3.6+: используйте inpsect.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 с одним исходным кодом, который переносится из прежней версииgetargspec()
API.
Как показывают другие ответы, 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__
строка. Очевидно, что это зависит от формата указанной строки, так что вряд ли является надежным!
inspect.getargspec() для удовлетворения ваших потребностей
from inspect import getargspec
def func(a, b):
pass
print len(getargspec(func).args)
Это решение для получения количества обязательных аргументов функции (*)
Многие из предложенных здесь решений не работают для этой цели, если используются некоторые более необычные спецификации параметров (параметры только для позиции со значениями по умолчанию, параметры только для ключевых слов без значений по умолчанию и т. д.).
from typing import Callable, Any
import inspect
def get_mandatory_argcount(f: Callable[..., Any]) -> int:
"""Get the number of mandatory arguments of a function."""
sig = inspect.signature(f)
def parameter_is_mandatory(p: inspect.Parameter) -> bool:
return p.default is inspect.Parameter.empty and p.kind not in (
inspect.Parameter.VAR_POSITIONAL,
inspect.Parameter.VAR_KEYWORD,
)
return sum(parameter_is_mandatory(p) for p in sig.parameters.values())
# mandatory keyword-only
def f1(b=2, *args, c, d=1, **kwds): pass
print(get_mandatory_argcount(f1))
# positional only with default
def f2(a=1, /, b=3, *args, **kwargs): pass
print(get_mandatory_argcount(f2))
(*) Я хотел бы поместить это как ответ на Программное определение количества параметров, требуемых функцией - вместо этого Python, но по какой-то причине этот вопрос помечен как дублирующий этот вопрос, несмотря на то, что он конкретно спрашивает о количестве требуемых аргументов, тогда как этот вопрос касается только общего количества аргументов.
В:
import inspect
class X:
def xyz(self, a, b, c):
return
print(len(inspect.getfullargspec(X.xyz).args))
Вне:
4
Примечание. Если бы xyz не находился внутри класса X и не имел "self", а только "a, b, c", то он напечатал бы 3.
Для python ниже 3.5 вы можете заменить inspect.getfullargspec
по inspect.getargspec
в коде выше.
Предполагая, что вы можете иметь дело с классом на основе
method
s или просто
function
s, вы можете сделать что-то вроде следующего.
Это автоматически вычитает один ввод, если ввод является методом класса (и, следовательно, включает
self
).
import types
def get_arg_count(fn):
extra_method_input_count=1 if isinstance(fn, types.MethodType) else 0
return fn.__code__.co_argcount-extra_method_input_count
Затем вы можете применять по мере необходимости к функциям или методам:
def fn1(a, b, c):
return None
class cl1:
def fn2(self, a, b, c):
return None
print(get_arg_count(fn1)) #=> 3
print(get_arg_count(cl1().fn2)) #=> 3
Принятый ответ Димитриса Фасаракиса Хиллиард предлагает получить параметры в строковом формате, но я думаю, что при синтаксическом анализе этой строки можно допустить ошибку, и поэтому я скорее создал список параметров, напрямую используя модуль проверки.
import inspect
def my_function(a,b,c):
#some code
pass
result=list(inspect.signature(my_function).parameters.keys())
print(result)
['a','b','c']