В моих Python проектах часто есть переменные, которые мне нужно разделить между модулями. Я знаю, что это можно сделать с помощью аргументов для вызовов функций, но иногда удобнее создать один модуль global_vars.py и добавить туда все переменные, которые нужно разделить, что я часто и делаю. Эти переменные затем могут быть импортированы из любого другого модуля и легко доступны. Это обычно работает хорошо для меня. Однако иногда происходят неожиданные вещи.
Например:
У меня есть 3 файла:
main.py:
from global_vars import var
from mod import modify_variable
print(f"{hex(id(var))} - address of var in main module after import")
modify_variable()
print(f"{hex(id(var))} - address of var in main module after modify_variable() call")
global_vars.py:
var = 'hi'
print(f"{hex(id(var))} - address of var during import")
mod.py: из global_vars import var
def modify_variable():
global var
print(f"{hex(id(var))} - address of var before modifying it in modify_variable()")
var = 'hello'
print(f"{hex(id(var))} - address of var after modifying it in modify_variable()")
Если вы запустите main.py с Python3, вы получите вывод, который выглядит следующим образом:
0x7f0f993bb7f0 - address of var during import
0x7f0f993bb7f0 - address of var in main module after import
0x7f0f993bb7f0 - address of var before modifying it in modify_variable()
0x7f0f993bb870 - address of var after modifying it in modify_variable()
0x7f0f993bb7f0 - address of var in main module after modify_variable() call
По сути, все ведет себя как ожидалось, пока мы не назовем modify_variable
В пределах modify_variable
адрес var
начинается, как мы ожидаем. Затем мы присваиваем ему новую строку. Это делает несколько вещей:
- Создает новую строку в памяти
- Изменяет
var
, указывая на адрес этой новой строки - сборщик мусора, вероятно, в какой-то момент очистит адрес старой строки
. Учитывая это, я ожидаю, что последняя проверка адреса var
также будет указывать на адрес нового строка. Поэтому я ожидаю, что результат будет выглядеть так:
0x7f0f993bb7f0 - address of var during import
0x7f0f993bb7f0 - address of var in main module after import
0x7f0f993bb7f0 - address of var before modifying it in modify_variable()
0x7f0f993bb870 - address of var after modifying it in modify_variable()
0x7f0f993bb870 - address of var in main module after modify_variable() call
, но это не так. var
в modify_variable
и var
в main.py теперь указывают на совершенно разные адреса и больше не могут использовать одни и те же данные.
Что случилось? Из того, что я прочитал, если бы я не использовал global var
в mod.py
, вполне возможно, что я создал бы локальную переменную с тем же именем, что и глобальная переменная var
, что могло бы вызвать описанные выше симптомы. , но использование global var
, как я, гарантирует, что я имею дело с global_vars.var
, не так ли?