Получить список /tuple/dict аргументов, переданных функции?

Учитывая следующую функцию:

def foo(a, b, c):
    pass

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

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

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

Ответ 1

Вы можете использовать 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}

Я предпочел бы построить dict или список переменных, которые вам нужны в верхней части вашей функции, как это предлагается в других ответах. Это более ясное и более четкое представление о намерении вашего кода, IMHO.

Ответ 2

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

def foo(x):
    return x

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

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

Ответ 3

Я использовал бы *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
    ...

Ответ 4

Из принятого ответа из дубликата (старше?) вопроса fooobar.com/questions/38073/...:

    frame = inspect.currentframe()
    args, _, _, values = inspect.getargvalues(frame)

Ответ 5

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

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

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

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

Ответ 6

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

args = [a, b, c]

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

args = (a, b, c)

Ответ 7

Одно решение, использующее декораторы, здесь.

Ответ 8

class my_class():
        compulsory_default_kwargs = {'p':20,'q':30,'r':40}
        formal_args_names = ['var1','var2']
        def __init__(self,*args,**kwargs):
            for key , value in locals().items():
                if((key == 'args')):
                    if(len(args) == len(my_class.formal_args_names)):
                        for key_name , arg_value in zip(my_class.formal_args_names,args):
                            setattr(self,key_name,arg_value)
                    else:
                        raise Exception ('Error - Number of formal arguments passed mismatched required {} whereas passed {}'.format(len(my_class.formal_args_names),len(args)))

                elif((key == 'kwargs') & (len(kwargs)!=0)):
                    for kw_key , kw_value in kwargs.items():
                        if kw_key in my_class.compulsory_default_kwargs.keys():
                            setattr(self,kw_key,kw_value)
                        else:
                            raise Exception ('Invalid key-word argument passed {}'.format(kw_key))
                #elif((key!='self') & (key!='kwargs') ):
                   # setattr(self,key,value)
            for key , value in my_class.compulsory_default_kwargs.items():
                if key not in kwargs.keys():
                    setattr(self,key,value)


    this_value = 'Foo'    
    my_cl = my_class(3,this_value,p='B',r=10)
    my_cl.__dict__