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

StackOverflow https://stackoverflow.com/questions/5860974

Вопрос

Есть ли более успешный способ написать это?

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)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top