Python import global nom n'est pas défini
J'ai une application qui s'exécute sur Postgres & Mysql. Chaque programme de vérifications afin de déterminer la base de données et les importations, soit postgres_db comme db_util ou mysql_dt comme db_util. Tous fonctionne bien lorsque le code dans les principales références db_util, mais si une classe est importé, la référence à db_util n'est pas défini.
J'ai créé le suivant: pour les classes et les principaux pour tester le problème et trouvé un autre effet secondaire. Les Classes B & C référence ClassA en vertu d'importation différents cas. B & C sont identiques à l'exception de B est dans main et C est importé.
ClassX.py
class ClassA(object):
def print_a(self):
print "this is class a"
class ClassC(object):
def ref_a(self):
print 'from C ref a ==>',
xa=ClassA()
xa.print_a()
def ref_ca(self):
print 'from C ref ca ==>',
xa=ca()
xa.print_a()
test_scope.py
from classes.ClassX import ClassA
from classes.ClassX import ClassA as ca
from classes.ClassX import ClassC as cb
class ClassB(object):
def ref_a(self):
print 'from B ref a ==>',
xa=ClassA()
xa.print_a()
def ref_ca(self):
print 'from B ref ca ==>',
xa=ca()
xa.print_a()
print 'globals:',dir()
print 'modules','ca:',ca,'cb:',cb,'CA:',ClassA
print ''
print 'from main'
xb=ClassB()
xb.ref_a()
xb.ref_ca()
print ''
print 'from imports'
xbs=cb()
xbs.ref_a()
xbs.ref_ca()
Et les résultats:
globals: ['ClassA', 'ClassB', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'ca', 'cb']
modules ca: <class 'classes.ClassX.ClassA'> cb: <class 'classes.ClassX.ClassC'> CA: <class 'classes.ClassX.ClassA'>
from main
from B ref a ==> this is class a
from B ref ca ==> this is class a
from imports
from C ref a ==> this is class a
from C ref ca ==>
Traceback (most recent call last):
File "test_scope.py", line 32, in <module>
xbs.ref_ca()
File "R:\python\test_scripts\scope\classes\ClassX.py", line 13, in ref_ca
xa=ca()
NameError: global name 'ca' is not defined
Press any key to continue . . .
De mon test, je vois que l'objet autorité de certification (importés en tant qu') n'est pas disponible à la ClassC, cependant, le module ClassA est disponible (importés sans que).
- Pourquoi la différence entre l'importation et à l'importation comme comportement? Je ne sais pas pourquoi d'alimentation variables globales ne sont pas disponibles pour les classes principales importations.
- Ce qui est une bonne approche pour déterminer dynamiquement approprié db_util d'un module d'import et d'avoir accessible à d'autres classes importées?
Mise à jour:
Après la lecture encore un autre post sur les espaces de noms: "La visibilité des variables globales à partir de modules importés", je comprends que, dans mon exemple ci-dessus la raison classA est disponible à ClassC est qu'Un & C sont dans le même fichier importé, donc le même espace de noms.
Donc, la question qui reste est une question de conception:
si j'ai un code comme ceci:
if db == 'MySQL':
from mysql_db import db_util
elif db == 'Postgres'
from postgres_db import db_util
Ce qui est une bonne approche pour faire db_util disponible pour tous les modules importés?
Mise à JOUR:
de la reponse par Blckknght, j'ai ajouté le code
cb.ca =ca
à la scope_test script. Cela nécessite l'appel de classe à xa=ca() être changé à xa=auto.ca(). Je pense aussi que l'ajout d'objets d'une classe à partir de l'extérieur de la classe, bien que Python permet, n'est pas une bonne conception de la méthodologie de faire du débogage d'un cauchemar.
Cependant, depuis que je pense que les modules et les classes doivent être autonomes ou de déclarer expressément que leurs dépendances, je vais mettre en application la classe comme ceci, à l'aide de l'exemple de code ci-dessus.
sortir ClassA et ClassC de modules distincts et au sommet de ClassC, avant la définition de la classe, ne les importations
from ClassA import ClassA
from ClassA import ClassA as ca
class ClassB(object):
et dans ma situation réelle, où j'ai besoin d'importer le db_util module en plusieurs modules
ci.py #nouveau module pour sélectionner la classe de décibels
if db == 'MySQL':
from mysql_db import db_util
elif db == 'Postgres'
from postgres_db import db_util
dans chaque module nécessitant la db_util classe
import ci
db_util=ci.db_util #add db_util to module globals
class Module(object):
Un problème avec ceci est qu'il exige que chaque module à l'aide de la db_util importer, mais il ne les dépendances connu.
Je vais fermer cette question et nous tenons à remercier Blckknght et Armin Rigo pour leurs réponses qui peuvent aider à clarifier cette question pour moi. Je vous serais reconnaissant de tout liés à la conception de la rétroaction.
OriginalL'auteur cswaim | 2013-05-02
Vous devez vous connecter pour publier un commentaire.
En Python, chaque module dispose de son propre espace de noms global. Lorsque vous effectuez une importation, vous ne faites qu'ajouter les modules importés vers le module actuel de l'espace de noms, pas à l'espace de noms d'un autre module. Si vous voulez le mettre dans un autre espace de noms, vous devez dire à Python explicitement.
main.py:
Les autres modules:
Notez que vous ne pouvez pas habituellement utiliser votre module principal (qui est exécuté en tant que script) comme un espace de noms partagé. C'est parce que Python utilise le module de
__name__
attribut pour déterminer comment mettre en cache le module (de sorte que vous obtenez toujours la même objet à partir de plusieurs importations), mais un script est toujours__name__
de"__main__"
plutôt que son nom réel. Si un autre module importationsmain
, ils ont séparé (en double) copie!cb.ca =ca
à mon test_scope.py le script ci-dessus, immédiatement après l'importation, la pensée qui va ajouter de la ca de la cb de l'espace de noms. Je suis encore en train mondiale ne sont pas définies et lorsque j'imprime les valeurs globales de la ClassC, il imprime globals: ['auto'] -- aucune référence à l'autorité de certification et l'erreur est toujours présente. Qu'ai-je manqué?J'ai raté ca doit être référencé en tant que soi.ca comme ca est maintenant définies dans la classe.
OriginalL'auteur Blckknght
Vous approchez le problème avec le mauvais point de vue. Chaque module est un espace de noms qui commence à vide et est rempli avec un nom (typiquement) pour chaque énoncé, il s'exécute:
Regardant ClassX.py nous voyons que le nom
ca
n'est pas défini dans le présent module, maisClassA
etClassC
sont. Pour que l'exécution de la lignexa=ca()
de ClassX.py échoue.En général, l'idée est que chaque module importe ce dont il a besoin. Vous pouvez également corriger un nom "dans" un module à partir de l'extérieur, mais cela est généralement considéré comme très mauvais style (réservé à des cas très particuliers).
OriginalL'auteur Armin Rigo