Динамически создавать переменные внутри функции - PullRequest
1 голос
/ 23 сентября 2008

Я хочу создать переменные внутри функции из словаря.

Допустим, у меня есть словарь

bar = {'a': 1, 'b': 2, 'c': 3}

и функция

def foo():
  pass

Что я хочу сделать, так это создать внутри функции переменные "foo" с именами каждого имени элемента словаря и значениями в качестве значений элемента словаря

Итак, в конце концов, это должно быть похоже на

def foo():
  a = 1
  b = 2
  c = 3

Возможно ли это вообще? И если да, то как это сделать?

Ответы [ 4 ]

3 голосов
/ 23 сентября 2008

Из вашего комментария, возможно, то, что вы действительно ищете, является чем-то вроде связки объектов:

class Bunch(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

b=Bunch(**form.cleaned_data)

print b.first_name, b.last_name

(Синтаксис ** потому, что объекты типа Bunch обычно используются как Bunch (foo = 12, bar = 'blah') - в вашем случае это не используется, но я оставил его для согласованности с обычным использованием)

Это требует "б". Префикс для доступа к вашим переменным, но если вы думаете об этом, это не так уж плохо. Подумайте, что произойдет, если кто-то создаст запрос POST для перезаписи переменных, которые вы не ожидаете перезаписать - это упрощает создание сбоев и DOS-атак и может легко привести к более серьезным уязвимостям безопасности. *

2 голосов
/ 23 сентября 2008

Ваш вопрос не ясен.

Если вы хотите «установить» указанные переменные, когда foo не запущен, нет, вы не можете. Пока еще нет объекта фрейма для "установки" локальных переменных.

Если вы хотите сделать это в теле функции, вам не следует (см. документацию по питону *1006* для locals ()).

Однако, вы можете сделать foo.__dict__.update(bar), и тогда вы сможете получить доступ к этим переменным даже изнутри функции как foo.a, foo.b и foo.c. Вопрос в том, почему вы хотите это сделать, и почему класс не подходит для ваших целей?

1 голос
/ 23 сентября 2008

Спасибо, ребята, я понял. Я не должен делать такие вещи. Но если вам интересно то, что я пытался сделать, это как-то сократить количество строк в моем представлении функции в django У меня есть форма со многими полями, и вместо того, чтобы получать каждое поле в виде:

first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name'] ..

Я думал взять каждое имя атрибута моего класса формы и перебрать его. Вот так:

for name in ProfileRegistration.base_fields.__dict__['keyOrder']:
   # and here the variables that i tried to assign
1 голос
/ 23 сентября 2008

Зачем тебе это делать? Если вы на самом деле ничего не делаете с переменными внутри функции, функция, которая просто присваивает несколько переменных, а затем отбрасывает их, неотличима от def foo (): pass (оптимизатор будет оправдан в создании точно такого же байт-кода).

Если вы также хотите динамически добавлять код, который использует значения, то вы можете сделать это с помощью exec (хотя, если это не действительно код пользовательского ввода, почти наверняка есть лучшие способы сделать то, что вы хотите). например:

some_code = '  return a+b+c'
exec "def foo():\n  " + '\n  '.join('%s = %s' for k,v in bar.items()) + '\n' + some_code

(Обратите внимание, что ваш код должен иметь отступ на том же уровне.)

С другой стороны, если вы действительно хотите присвоить эти значения функции object (так что вы можете сделать foo.a и получить 1 - обратите внимание, что ваш пример кода не делает этого), Вы можете сделать это:

for key, val in bar.items():
    setattr(foo, key, val)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...