Учитывая функцию Python:
def a_method(arg1, arg2):
pass
Как я могу извлечь количество и имена аргументов. То есть, учитывая, что у меня есть ссылка наfunc
, я хочу func.[something]
вернуться ("arg1", "arg2")
.
Сценарий использования для этого заключается в том, что у меня есть декоратор, и я хочу использовать аргументы метода в том же порядке, в котором они отображаются для фактической функции в качестве ключа. Т.е. как будет выглядеть декоратор, который напечатан "a,b"
при звонке a_method("a", "b")
?
Ответы:
Посмотрите на
inspect
модуль - он проведет проверку различных свойств объекта кода для вас.Другими результатами являются имена переменных * args и ** kwargs и предоставленные значения по умолчанию. то есть.
Обратите внимание, что некоторые вызовы могут не быть интроспективными в некоторых реализациях Python. Например, в CPython некоторые встроенные функции, определенные в C, не предоставляют метаданных об их аргументах. В результате вы получите,
ValueError
если используетеinspect.getfullargspec()
встроенную функцию.Начиная с Python 3.3, вы можете использовать
inspect.signature()
для просмотра подписи вызова вызываемого объекта:источник
(4,)
соответствует параметру ключевого словаc
?inspect.getargspec
является устаревшим , но заменаinspect.getfullargspec
.В CPython количество аргументов
и их имена в начале
Это детали реализации CPython, так что это, вероятно, не работает в других реализациях Python, таких как IronPython и Jython.
Один из переносимых способов допустить «сквозные» аргументы - определить вашу функцию с помощью сигнатуры
func(*args, **kwargs)
. Это часто используется, например, в matplotlib , где внешний уровень API передает множество ключевых аргументов в API более низкого уровня.источник
*args
, например:def foo(x, *args, y, **kwargs): # foo.__code__.co_argcount == 1
В методе декоратора вы можете перечислить аргументы исходного метода следующим образом:
Если
**kwargs
это важно для вас, то это будет немного сложно:Пример:
источник
Я думаю, что вы ищете метод местных жителей -
источник
Версия Python 3:
Метод возвращает словарь, содержащий как args, так и kwargs.
источник
[:fn.__code__.co_argcount]
это очень важно, если вы ищете аргументы функции - в противном случае в нее также входят имена, созданные внутри функции.Вот то, что я думаю, будет работать для того, что вы хотите, используя декоратор.
Запустите его, он даст следующий вывод:
источник
Python 3.5+:
Итак, ранее:
Сейчас:
Тестировать:
Учитывая, что у нас есть функция 'function', которая принимает аргумент 'arg', она будет оцениваться как True, иначе как False.
Пример из консоли Python:
источник
В Python 3. + с
Signature
объектом под рукой, простой способ получить соответствие между именами аргументов и значениями, это использовать метод Signaturebind()
!Например, вот декоратор для печати такой карты:
источник
Вот еще один способ получить параметры функции без использования какого-либо модуля.
Вывод:
источник
Возвращает список имен аргументов, заботится о частичках и обычных функциях:
источник
Обновление для ответа Брайана :
Если функция в Python 3 имеет аргументы только для ключевых слов, вам необходимо использовать
inspect.getfullargspec
:дает это:
источник
В Python 3, ниже, чтобы сделать
*args
и**kwargs
вdict
(использоватьOrderedDict
для Python <3,6 для поддержанияdict
заказов):источник
inspect.signature
очень медленно Самый быстрый способисточник
Чтобы обновить немного ответ Брайана , теперь есть хороший портировать из
inspect.signature
который вы можете использовать в более старых версиях Python:funcsigs
. Так что мои личные предпочтенияДля интереса, если вам интересно играть с
Signature
объектами и даже динамически создавать функции со случайными подписями, вы можете взглянуть на мойmakefun
проект.источник
Как насчет
dir()
иvars()
сейчас?Кажется, делает именно то, что просят супер просто ...
Должен вызываться из области действия функции.
Но будьте осторожны, что он вернет все локальные переменные, поэтому при необходимости обязательно сделайте это в самом начале функции.
Также обратите внимание, что, как указано в комментариях, это не позволяет делать это вне области видимости. Так что не совсем сценарий ОП, но все равно соответствует заголовку вопроса. Отсюда и мой ответ.
источник