Je me suis heurté à un mur en important des modules dans un script Python. Je vais faire de mon mieux pour décrire l'erreur, pourquoi je la rencontre, et pourquoi j'utilise cette approche particulière pour résoudre mon problème (que je vais décrire dans une seconde) :
Supposons que j'ai un module dans lequel j'ai défini certaines fonctions/classes utilitaires, qui font référence à des entités définies dans l'espace de noms dans lequel ce module auxiliaire sera importé (laissons "a" être une telle entité) :
module1 :
def f():
print a
Et puis j'ai le programme principal, où "a" est défini, dans lequel je veux importer ces utilitaires :
import module1
a=3
module1.f()
L'exécution du programme déclenchera l'erreur suivante :
Traceback (most recent call last):
File "Z:\Python\main.py", line 10, in <module>
module1.f()
File "Z:\Python\module1.py", line 3, in f
print a
NameError: global name 'a' is not defined
Des questions similaires ont été posées dans le passé (il y a deux jours, d'uh) et plusieurs solutions ont été suggérées, mais je ne pense pas qu'elles correspondent vraiment à mes besoins. Voici mon contexte particulier :
J'essaie de faire un programme Python qui se connecte à un serveur de base de données MySQL et affiche/modifie les données avec une interface graphique. Pour des raisons de propreté, j'ai défini le groupe de fonctions auxiliaires/utilitaires liées à MySQL dans un fichier séparé. Cependant, elles ont toutes une variable commune, que j'avais initialement définie comme suit à l'intérieur de le module utilitaire, et qui est le curseur du module MySQLdb. J'ai réalisé par la suite que l'objet curseur (qui est utilisé pour communiquer avec le serveur de données) doit être défini dans le module principal, afin que le module principal et tout ce qui est importé dans ce module puissent accéder à cet objet.
Le résultat final serait quelque chose comme ceci :
Utilitaires_module.py :
def utility_1(args):
code which references a variable named "cur"
def utility_n(args):
etcetera
Et mon module principal :
program.py :
import MySQLdb, Tkinter
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from utilities_module import *
Et puis, dès que j'essaie d'appeler l'une des fonctions utilitaires, cela déclenche l'erreur susmentionnée "nom global non défini".
Une suggestion particulière était d'avoir une déclaration "from program import cur" dans le fichier utilitaire, comme ceci :
Utilitaires_module.py :
from program import cur
#rest of function definitions
program.py :
import Tkinter, MySQLdb
db=MySQLdb.connect(#blahblah) ; cur=db.cursor() #cur is defined!
from utilities_module import *
Mais c'est de l'importation cyclique ou quelque chose comme ça et, en fin de compte, ça se plante aussi. Donc ma question est :
Comment faire en sorte que l'objet "cur", défini dans le module principal, soit visible par les fonctions auxiliaires qui y sont importées ?
Merci pour votre temps et mes plus sincères excuses si la solution a été postée ailleurs. Je n'arrive pas à trouver la réponse moi-même et je n'ai plus d'astuces dans mon livre.