2014-10-07 2 views
0

В настоящее время я работаю над игровым проектом на Python, и я нахожусь в стороне от «концепций», стоящих за Python, поскольку я использую такие языки, как C или Java.Глобальные переменные в Python для всех модулей

Я попытался «разделить» мой проект в нескольких файлах (которые называются модулями, если я не ошибаюсь, хотя они все находятся в той же папке, что и в исходных файлах C) с разными темами: objects.py , map.py, rendering.py и т. Д. Они содержат разные классы и функции, связанные с этими понятиями. У меня есть main.py, который содержит все мои «основные» функции (например, new_game и т. Д.), А также первый «звонок», который вызовет main_menu.

У меня также есть файл constants.py, где хранятся постоянные значения. Теперь дело в том, что у меня есть несколько «глобальных» переменных и объектов в моей игре: объект игрока, карта и т. Д. Я хочу, чтобы эти переменные были глобальными во всех модулях и иметь возможность получать и изменять их везде.

Сначала я создал файл global_variables.py, в котором перечислены все мои переменные (например, map = None, player = None и т. Д.), Ожидая изменения их через другие модули.

Проблема в том, что каждый раз, когда я снова вызывал импорт global_variables, он пробежал весь код и повторно инициализировал все из них до None, чего я, очевидно, не хочу.

Я прочитал в другой теме stackoverflow поток: создание функции init() в моем файле, где я бы инициализировал все переменные и объявил их глобальными. Таким образом, я вызываю global_variables.init() один раз, а затем могу просто сделать global_variables.player, чтобы получить доступ к плееру и изменить его.

Это хорошо работает, но я нахожу его сухим. У меня есть тонна global foo, а затем foo = None, и он чувствует себя как ненужные строки кода. Кроме того, IDE не могут «получить доступ» к переменным, когда я ввожу global_variables. , он не предполагает, что переменные являются автозаполнениями, что довольно больно.

Так есть ли другой способ сделать это? Идея заключалась бы в том, чтобы «объявить» переменные из любой функции, чтобы IDE поняли, что они есть, но только «инициализируют» их один раз, чтобы я не удалял их при каждом изменении модуля global_variables.

ответ

3

Проблема в том, что каждый раз, когда я снова вызывал импорт global_variables, он пробежал весь код и повторно инициализировал все из них в None, чего я, очевидно, не хочу.

Нет, Python не будет повторно запускать код при импорте этого модуля несколько раз. Модуль выполняется только один раз, создавая объект модуля, который затем повторно используется для последующего импорта.

Таким образом, использование модуля для всех ваших глобальных программ в порядке. Просто убедитесь, что вы импортировать модуль и присвоить обратно атрибутов этого объекта модуля:

import global_variables 

global_variables.name = 'Inigo Montoya' 

и любой другой модуль, который импортирует global_variables будет видеть global_variables.name, как установлено в 'Inigo Montoya'. No init() функция требуется.

ли не использование from global_variables import name, потому что создает новое имя name в вашем модуле, который не будет видеть новые значения, если другой код global_variables.name повторной привязки к другому значению.

+0

Тогда я не понимаю. Я импортировал global_variables в качестве gv и имел функцию, которая, например, инициализировала gv.map с циклом double for (так как он моделировал массив из 2-х измерений). Тогда я бы назвал еще одну функцию, оттуда, которая была в другом модуле, чтобы действовать на карте, и это покажет мне, что map = None. Поэтому никаких изменений в карте не было. И я нашел решение init() как ответ на эту проблему, с которой столкнулись другие люди. – lap0573

+1

@ lap0573: вам нужно использовать 'import global_variables', * not *' из global_variables import map'; последний по-прежнему будет привязан к предыдущему значению, если изменилось значение 'global_variables.map'. –

+1

@ lap0573: в Python все имена (атрибуты, locals, globals) и элементы в списках, кортежи, наборы и словари и т. Д. Являются * ссылками *. Если вы перепечатаете такое имя, другие имена, ссылающиеся на старый объект, не будут отскакивать от нового объекта. Используя 'modulename.name', вы всегда ссылаетесь на один атрибут (глобальное имя в этом модуле) и всегда видите, к чему это привязано. –

Смежные вопросы