Получить список /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__