Я просмотрел ряд существующих вопросов об исключениях NameError, когда скрипты запускаются с операторами exec или execfile() в Python, но пока не нашел хорошего объяснения следующего поведения.
Я хочу сделать простую игру, которая создает объекты сценария во время выполнения с помощью execfile(). Ниже приведены 4 модуля, которые демонстрируют проблему (пожалуйста, потерпите меня, это настолько просто, насколько я мог это сделать!). Основная программа просто загружает скрипт с помощью execfile(), а затем вызывает диспетчер скриптов для запуска объектов скрипта:
# game.py
import script_mgr
import gamelib # must be imported here to prevent NameError, any place else has no effect
def main():
execfile("script.py")
script_mgr.run()
main()
Файл сценария просто создает объект, который воспроизводит звук, а затем добавляет объект в список в диспетчере сценариев:
script.py
import script_mgr
#import gamelib # (has no effect here)
class ScriptObject:
def action(self):
print("ScriptObject.action(): calling gamelib.play_sound()")
gamelib.play_sound()
obj = ScriptObject()
script_mgr.add_script_object(obj)
Менеджер скриптов просто вызывает функцию action() каждого скрипта:
# script_mgr.py
#import gamelib # (has no effect here)
script_objects = []
def add_script_object(obj):
script_objects.append(obj)
def run():
for obj in script_objects:
obj.action()
Функция gamelib определена в четвертом модуле, доступ к которому вызывает затруднения:
# gamelib.py
def play_sound():
print("boom!")
Приведенный выше код работает со следующим выводом:
mhack:exec $ python game.py ScriptObject.action(): calling gamelib.play_sound() boom! mhack:exec $
Однако, если я закомментирую оператор «import gamelib» в game.py и раскомментирую «import gamelib» в script.py, я получу следующую ошибку:
mhack:exec $ python game.py ScriptObject.action(): calling gamelib.play_sound() Traceback (most recent call last): File "game.py", line 10, in main() File "game.py", line 8, in main script_mgr.run() File "/Users/williamknight/proj/test/python/exec/script_mgr.py", line 12, in run obj.action() File "script.py", line 9, in action gamelib.play_sound() NameError: global name 'gamelib' is not defined
Мой вопрос: 1) Зачем нужен импорт в модуле 'game.py', который выполняет скрипт? 2) Почему не работает импорт 'gamelib' из модуля, в котором он указан (script.py), или из модуля, в котором он вызывается (script_mgr.py)?
Это происходит на Python 2.5.1