Je suis tombé sur un mur en important des modules dans un script Python. Je ferai de mon mieux pour décrire l'erreur, pourquoi je la rencontre et pourquoi j'attache cette approche particulière pour résoudre mon problème (que je décrirai dans une seconde):
Supposons que j'ai un module dans lequel j'ai défini des fonctions / classes utilitaires, qui se réfèrent aux entités définies dans l'espace de noms dans lequel ce module auxiliaire sera importé (soit "a" une telle entité):
module 1:
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 vraiment qu'elles correspondent à mes besoins. Voici mon contexte particulier:
J'essaie de créer un programme Python qui se connecte à un serveur de base de données MySQL et affiche / modifie les données avec une interface graphique. Par souci de propreté, j'ai défini le tas de fonctions auxiliaires / utilitaires liées à MySQL dans un fichier séparé. Cependant, ils ont tous une variable commune, que j'avais initialement définie dans le module utilitaires, et qui est l' objet curseur du module MySQLdb. J'ai réalisé plus tard que l' objet curseur (qui est utilisé pour communiquer avec le serveur db) devait être défini dans le module principal, de sorte que le module principal et tout ce qui y est importé puisse accéder à cet objet.
Le résultat final serait quelque chose comme ceci:
utilities_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'essaye d'appeler l'une des fonctions utilitaires, cela déclenche l'erreur "nom global non défini" susmentionnée.
Une suggestion particulière était d'avoir une instruction "from program import cur" dans le fichier utilitaires, comme ceci:
utilities_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 une importation cyclique ou quelque chose comme ça et, en bout de ligne, ça plante aussi. Ma question est donc:
Comment diable puis-je rendre l'objet "cur", défini dans le module principal, 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é publiée ailleurs. Je ne trouve tout simplement pas la réponse moi-même et je n'ai plus d'astuces dans mon livre.
db
(et cur
, si vous insistez) dans un module séparé qui les deux program
et de l' utilities_module
importer. De cette façon, vous n'obtenez pas de dépendances circulaires (importation de programme à partir de modules importés par le programme) et la confusion qui les accompagne.
fetch_all
parcourir deux listes à la place. , ou simplement pour que vous puissiez avoir deux threads / greenlets / callback-chains / tout ce qui utilise la base de données sans conflits).