Подтвердить что ты не робот

Python: использование vars() для назначения строки переменной

Мне очень полезно иметь возможность создавать новые переменные во время выполнения и создавать словарь результатов для последующей обработки, т.е. записывать в файл:

myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    vars()[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.
    myDict[temp] = vars(temp)

который создает запись словаря [result1: data1], которую я могу вызвать с myDict [result1]. Я использую vars(), не понимая, что я делаю. Я принимаю его vars() возвращает словарь с локальными переменными (?) И

vars() [x] = y

создает новую запись словаря [x: y]?

У меня есть script, где я передаю словарь, подготовленный с помощью {input1: data1, input2: data2}, и я использую этот метод для итерации по всем значениям, сохранения всех результатов и вывода их в файл, Этот бит кода находится внутри функции внутри класса и работает.

Мой источник недоразумений заключается в том, что я читал разные сообщения о том, как нельзя смириться с locals() и как vars() эквивалентен (?) locals() или globals()..

Итак, мой вопрос (по крайней мере) в два раза:

1.Что именно делает vars(), или, в частности, vars() [x] = y do,

2.Какой объем этого словаря (что мне нужно иметь в виду, когда пишу большие программы

3. Хорошая практика программирования.

Спасибо заранее!

4b9b3361

Ответ 1

Питонический способ создания последовательности переменных

Если вам нужна последовательность переменных, создайте последовательность. Вместо того, чтобы создавать независимые переменные типа:

variable0
variable1
variable2
variable3

Вы должны посмотреть на создание list. Это похоже на то, что предлагает S.Lott(у S.Lott обычно есть хорошие советы), но более аккуратно отображает ваш цикл for:

sequence = []
for _ in xrange(10):
    sequence.append(function_that_returns_data())

(Обратите внимание, что мы отбрасываем переменную цикла (_). Мы просто пытаемся получить 10 проходов.)

Затем ваши данные будут доступны как:

sequence[0]
sequence[1]
sequence[2]
sequence[3]
[...]
sequence[9]

В качестве дополнительного бонуса вы можете:

for datum in sequence:
    process_data(datum)

Сначала вы можете подергивать, когда ваша последовательность начинается с 0. Вы можете пройти через различные искажения, чтобы ваши фактические данные начинались с 1, но это больнее, чем это стоит. Я рекомендую просто привыкнуть к спискам на основе нуля. Все вокруг них построено, и они начинают чувствовать себя довольно быстро.

vars() и locals()

Теперь, чтобы ответить на другую часть вашего вопроса. vars() (или locals()) обеспечивает низкий уровень доступа к переменным, созданным python. Таким образом, следующие две строки эквивалентны.

locals()['x'] = 4
x = 4

Объем vars()['x'] в точности совпадает с областью x. Одна из проблем с locals() (или vars()) заключается в том, что она позволит вам помещать материал в пространство имен, которое вы не можете получить из пространства имен обычными способами. Таким образом, вы можете сделать что-то вроде этого: locals()[4] = 'An integer', но вы не можете получить это обратно, не используя locals снова, потому что локальное пространство имен (как и все пространства имен python) предназначено только для хранения строк.

>>> x = 5
>>> dir()
['__builtins__', '__doc__', '__name__', 'x']
>>> locals()[4] = 'An integer'
>>> dir()
[4, '__builtins__', '__doc__', '__name__', 'x']
>>> x
5
>>> 4
4
>>> locals()[4]
'An integer'

Обратите внимание, что 4 не возвращает то же самое, что и locals() [4]. Это может привести к неожиданным, трудным для отладки проблемам. Это одна из причин избежать использования locals(). Другим является то, что в целом сложность заключается в том, чтобы делать вещи, которые python обеспечивает более простые, менее подверженные ошибкам способы выполнения (например, создание последовательности переменных).

Ответ 2

Сделайте это вместо этого. Это проще.

myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.

Это все, что вам нужно делать.

Результаты будут myDict['variable1'] через myDict['variable9']

Вам редко нужно vars() или locals(). Просто прекратите использовать их и используйте обычные переменные и обычные словари. Старайтесь избегать вещей, которые вы не понимаете, и придерживайтесь простых, очевидных вещей.

Ответ 3

Из справки для vars,

вары (...)     vars ([object]) → словарь

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

Вы используете его без vars, поэтому давайте посмотрим на помощь для locals()

локальные (...)     locals() → словарь

Update and return a dictionary containing the current scope local

переменные.

Итак, это отвечает на два первых вопроса. vars() возвращает словарь для локальных переменных, которые индексируются по имени переменной в виде строки. Область действия локальная.

Я не уверен в третьем вопросе, но это похоже на хак, который не является хорошим знаком. Я думаю, если вы будете осторожны в использовании этого только в правильной области, вы можете пройти с ним.

Ответ 4

jcdyer очень хорошо объясняет концепции, и Джастин Пил четко указывает, что делают vars() и locals(). Но небольшой пример всегда ускоряет понимание.

class Bull(object):

    def __init__(self):
        self.x = 1
        self.y = "this"

    def __repr__(self):
        return "Bull()"

    def test1(self):
        z = 5
        return vars()

    def test2(self):
        y = "that"
        return vars(self)

    def test3(self):
        return locals()

    def test4(self):
        y = 1
        return locals()

if __name__ == "__main__":
    b = Bull()
    print b.test1()
    print b.test2()
    print b.test3()
    print b.test4()
    print vars(b).get("y")

Результат:

{'self': Bull(), 'z': 5}
{'y': 'this', 'x': 1}
{'self': Bull()}
{'y': 1, 'self': Bull()}
this

Ответ 5

Я могу ответить на номер 3: это не хорошая практика программирования. Я не совсем понимаю, что вы пытаетесь выполнить, но я уверен, что есть более элегантный способ сделать это, не используя locals() (что совпадает с vars() в соответствии с help(vars) в интерактивной оболочке Python).