Передача аргументов ключевых слов к функции, когда локальные имена переменных одинаковы, что имена параметров функции
-
28-10-2019 - |
Вопрос
Есть ли более успешный способ написать это?
f(a=a, b=b, c=c, d=d, e=e)
Фон: у меня есть функция со слишком большим количеством аргументов
f(a, b, c, d, e):
pass
У меня есть программа, у меня есть локальные переменные, которые называются точно так же, как параметры функции.
a, b, c, d, e = range(5)
Я хотел бы вызвать функцию с помощью аргументов ключевых слов. Поскольку переменные называются одинаковыми, так будет выглядеть вызов.
g = f(a=a, b=b, c=c, d=d, e=e) # this can get very long
Конечно, я могу передать выводы, используя позицию вместо ключевых слов, подобных этому
g = f(a, b, c, d, e)
Но a
, b
, c
, d
, e
это просто имена переменных в этом примере, и легко увидеть правильный порядок. Однако, к сожалению, переменные в моей программе названы более сложными, и не существует легко заметного естественного порядка. Поэтому мне очень нравится передавать их ключевым словом, чтобы избежать любых ошибок.
Решение
Вы могли бы сделать что -то вроде следующего:
a, b, c, d, e = range(5)
arg_dict = lambda l: dict((k, globals()[k]) for k in l.split(', '))
arg_dict('a, b, c, d, e') => {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3}
, так что вы можете назвать свою функцию так:
f(**arg_dict('a, b, c, d, e'))
Это дает вам возможность точно указать, какие переменные вы хотите использовать. Альтернативный метод для этого, который не использует globals()
было бы использовать eval()
, но это может сделать использование лямбды потенциально небезопасным.
arg_dict = lambda l: dict(zip(l.split(', '), eval(l)))
Если вы предпочитаете пройти locals()
в как аргумент вместо использования globals()
В Lambda вы можете использовать следующее:
arg_dict = lambda l, d=locals(): dict((k, d[k]) for k in l.split(', '))
f(**arg_dict('a, b, c, d, e'))
Благодаря Senderle для locals()
предложения.
Другие советы
locals()
дает ваши местные переменные, так что вы могли бы сделать
def somewhere():
x = 3 # its a local
f(**locals()) # same as f(x=3)
Но вы наверняка увидите, насколько это очень хрупко.
Почему ты не можешь использовать ** кВт здесь?
def foo(**kw):
for k,v in kw.items():
print k,v
foo(a=2)
foo(a=3, b=4)
foo(nonsene=True, blather=False)