J'ai regardé un certain nombre de questions existantes sur les exceptions NameError lorsque les scripts sont exécutés avec des instructions exec ou execfile() en Python, mais n'ont pas encore trouvé une bonne explication du comportement suivant. Je veux faire un jeu simple qui crée des objets de script à l'exécution avec execfile(). Voici 4 modules qui démontrent le problème (s'il vous plaît, gardez-moi, c'est aussi simple que je pourrais le faire!). Le programme principal charge juste un script en utilisant execfile() et appelle ensuite un gestionnaire de script à exécuter les objets de script:Pourquoi l'importation n'interdit-elle pas NameError dans un script python exécuté avec 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()
Le fichier script crée simplement un objet qui joue un son et ajoute l'objet à une liste le gestionnaire de script:
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)
le gestionnaire de script appelle simplement la fonction de chaque action script():
# 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()
la fonction gamelib est définie dans un quatrième module, qui est une problématique à accéder:
# gamelib.py
def play_sound():
print("boom!")
Le code ci-dessus fonctionne avec la sortie suivante:
mhack:exec $ python game.py ScriptObject.action(): calling gamelib.play_sound() boom! mhack:exec $
Cependant, si je en commentaire la mention « gamelib importation » dans game.py et décommenter la 'gamelib d'importation' dans script.py, je reçois l'erreur suivante:
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
Ma question est: 1) Pourquoi l'importation nécessaire dans le module 'game.py', celui qui execs le script? 2) Pourquoi cela ne fonctionne-t-il pas d'importer 'gamelib' du module où il est référencé (script.py) ou du module où il est appelé (script_mgr.py)?
Cela se produit sur Python 2.5.1
Je connaissais les arguments globals et locals, mais je ne sais toujours pas comment les utiliser au mieux. Votre citation sur l'environnement m'aide à comprendre un peu mieux, mais je ne vois toujours pas pourquoi l'importation dans script.py ne fonctionne pas - cela ne le mettrait-il pas aussi dans l'environnement? –
Mis à jour ma réponse après quelques tests en imprimant des globals et des locaux. J'espère que ça aide;) – Yukiko
Oui, ça aide! Après vos observations sur les effets sur les globals et les locaux des importations, j'ai ajouté un peu de code de débogage pour imprimer les globals et les locaux et cela clarifie vraiment les choses maintenant. J'accepterai votre réponse, mais aussi poster une réponse de suivi avec mes résultats. –