Получить список / кортеж / dict аргументов, переданных функции? - PullRequest
56 голосов
/ 26 марта 2010

С учетом следующей функции:

def foo(a, b, c):
    pass

Как можно получить список / кортеж / dict / etc аргументов, переданных в , не создавая структуру самостоятельно ?

В частности, я ищу Python-версию ключевого слова JavaScript arguments или метода PHP func_get_args().

То, что я не ищу, - это решение, использующее *args или **kwargs; Мне нужно указать имена аргументов в определении функции (чтобы убедиться, что они передаются), но внутри функции я хочу работать с ними в виде списка или в стиле dict.

Ответы [ 7 ]

74 голосов
/ 26 марта 2010

Вы можете использовать locals(), чтобы получить подсказку о локальных переменных в вашей функции, например:

def foo(a, b, c):
    print locals()

>>> foo(1, 2, 3)
{'a': 1, 'c': 3, 'b': 2}

Это немного хакерски, однако, поскольку locals() возвращает все переменные в локальной области, а не только аргументы, переданные функции, поэтому, если вы не вызовете ее в самом верху функции, результат может содержит больше информации, чем вы хотите:

def foo(a, b, c):
    x = 4
    y = 5
    print locals()

>>> foo(1, 2, 3)
{'y': 5, 'x': 4, 'c': 3, 'b': 2, 'a': 1}

Я бы предпочел создать диктант или список переменных, которые вам нужны, в верхней части вашей функции, как предложено в других ответах. ИМХО, он более явный и сообщает о намерениях вашего кода более четко.

7 голосов
/ 27 марта 2010

Вы можете использовать модуль проверки:

def foo(x):
    return x

inspect.getargspec(foo)
Out[23]: ArgSpec(args=['x'], varargs=None, keywords=None, defaults=None)

Это дубликат этого и этого .

4 голосов
/ 26 марта 2010

Я бы использовал *args или **kwargs и выдал исключение, если аргументы не соответствуют ожиданиям

Если вы хотите, чтобы у вас были те же ошибки, что и у Python, вы можете сделать что-то вроде

def check_arguments(function_name,args,arg_names):
    missing_count = len(arg_names) - len(args)
    if missing_count > 0:
        if missing_count == 1:
            raise TypeError(function_name+"() missing 1 required positionnal argument: "+repr(arg_names[-1]))
        else:
            raise TypeError(function_name+"() missing "+str(missing_count)+" required positionnal argument: "+", ".join([repr(name) for name in arg_names][-missing_count:-1])+ " and "+repr(arg_names[-1]))

используя с чем-то вроде

def f(*args):
    check_arguments("f",args,["a","b","c"])
    #whatever you want
    ...
1 голос
/ 09 апреля 2015

Из принятого ответа на дубликат (старый?) Вопрос https://stackoverflow.com/a/582206/1136458:

    frame = inspect.currentframe()
    args, _, _, values = inspect.getargvalues(frame)
1 голос
/ 26 марта 2010

Одно решение с использованием декораторов - здесь .

1 голос
/ 26 марта 2010

Вы можете создать из них список, используя:

args = [a, b, c]

Вы можете легко создать из них кортеж, используя:

args = (a, b, c)
1 голос
/ 26 марта 2010

Вы указали параметры в заголовке?

Почему бы вам просто не использовать эту же информацию в теле?

def foo(a, b, c):
   params = [a, b, c]

Что я пропустил?

...