Получение имен параметров метода в Python - PullRequest
202 голосов
/ 20 октября 2008

Учитывая функцию Python:

def aMethod(arg1, arg2):
    pass

Как мне извлечь количество и имена аргументов. То есть, учитывая, что у меня есть ссылка на func, я хочу, чтобы func. [Что-то] возвращало ("arg1", "arg2").

Сценарий использования этого заключается в том, что у меня есть декоратор, и я хочу использовать аргументы метода в том же порядке, в котором они отображаются для фактической функции в качестве ключа. Т.е. как будет выглядеть декоратор, который печатает «a, b», когда я вызываю aMethod («a», «b»)?

Ответы [ 13 ]

1 голос
/ 11 декабря 2018

В питоне 3 ниже приведено *args и **kwargs в dict (используйте OrderedDict для python <3.6 для поддержания <code>dict ордеров):

from functools import wraps

def display_param(func):
    @wraps(func)
    def wrapper(*args, **kwargs):

        param = inspect.signature(func).parameters
        all_param = {
            k: args[n] if n < len(args) else v.default
            for n, (k, v) in enumerate(param.items()) if k != 'kwargs'
        }
        all_param .update(kwargs)
        print(all_param)

        return func(**all_param)
    return wrapper
0 голосов
/ 14 марта 2019

Чтобы немного обновить Ответ Брайана , теперь есть хороший бэкпорт inspect.signature, который можно использовать в более старых версиях Python: funcsigs. Так что мои личные предпочтения были бы на

try:  # python 3.3+
    from inspect import signature
except ImportError:
    from funcsigs import signature

def aMethod(arg1, arg2):
    pass

sig = signature(aMethod)
print(sig)

Для интереса, если вам интересно играть с Signature объектами и даже динамически создавать функции со случайными подписями, вы можете взглянуть на мой проект makefun.

0 голосов
/ 08 января 2017

А как насчет dir() и vars() сейчас?

Кажется, делает то, о чем спрашивают, просто супер ...

Должен вызываться из области действия функции.

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

Также обратите внимание, что, как указано в комментариях, это не позволяет делать это за пределами области видимости. Так что не совсем сценарий ОП, но все равно соответствует заголовку вопроса. Отсюда и мой ответ.

...