I looked at a number of existing questions about NameError exceptions when scripts are run with exec or execfile () statements in Python, but have not yet found a good explanation for the following behavior.
I want to create a simple game that creates script objects at runtime using execfile (). Below are 4 modules that demonstrate the problem (please take me, it is as simple as I could do it!). The main program simply loads the script using execfile () and then calls the script manager to run the script objects:
# 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()
The script file simply creates an object that plays the sound, and then adds the object to the list in the script manager:
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)
The script manager simply calls the action () function for each script:
# script_mgr.py
The gamelib function is defined in the fourth module, which is problematic for access:
# gamelib.py def play_sound(): print("boom!")
The above code works with the following output:
mhack: exec $ python game.py
ScriptObject.action (): calling gamelib.play_sound ()
boom!
mhack: exec $
However, if I comment out the import gamelib statement in game.py and uncomment the import gamelib statement in script.py, I get the following error:
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 My question is: 1) Why is import needed in the "game.py" module that executes the script? 2) Why doesn’t it work to import "gamelib" from the module to which it refers (script.py) or the module where it is called (script_mgr.py)?
This happens on Python 2.5.1