Передача аргументов ключевых слов в функцию, когда имена локальных переменных совпадают с именами параметров функции - PullRequest
7 голосов
/ 02 мая 2011

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

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 - это просто имена переменных в этом примере, и легко увидеть правильный порядок.Однако, к сожалению, переменные в моей программе названы более сложно, и не существует легко различимого естественного порядка.Поэтому мне очень нравится передавать их по ключевым словам, чтобы избежать ошибок.

Ответы [ 3 ]

5 голосов
/ 02 мая 2011

Вы можете сделать что-то вроде следующего:

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() в лямбда-выражении, вы можете использовать следующее:

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() предложений.

2 голосов
/ 02 мая 2011

locals() дает ваши локальные переменные, чтобы вы могли сделать

def somewhere():
  x = 3 # its a local
  f(**locals()) # same as f(x=3)

но вы наверняка можете увидеть, насколько это хрупко.

1 голос
/ 02 мая 2011

Почему вы не можете использовать ** квт здесь?

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)
...