Я рассмотрел ряд существующих вопросов об исключениях 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