#1 Le 18/06/2012, à 14:28
- PengouinPdt
[python] espace de nom, object global
Bonjour,
J'ai un problème de compréhension avec l'espace de nom, et la portée globale des objects avec Python (Problème que je n'ai pas eu avec PHP, Java).
Pour brosser celui, je vais d'abord définir l'architecture de mon appli.
- mon lanceur nommé 'Hashable.py'
|- un répertoire nommé 'modules' dans lequel, j'ai quatre autres scripts, chacun étant une class, plus le script __init__.py
+ d'autres répertoires ( de locales, de licence, ...)
Dans mon lanceur, j'ai le code suivant :
#
## Variables
#
libgui = "gtkbuilder"
#libgui = "libglade"
#
# *** DONT TOUCH BELOWE!
#
# modules needed
import os, sys
sys.path.append( os.getcwd() + "/modules")
modules = __import__( 'modules' )
print modules.__all__ #affiches des différents noms de scripts dans le répertoire modules
def auto_loader():
mod = {}
for m in modules.__all__:
#print m
#mod[m] = ( getattr( __import__('modules', globals(), locals(), [ m ], -1), m ) )
#__import__( m )
globals()[m] = getattr( __import__('modules', globals(), locals(), [ m ], -1), m )
try:
'''
from modules import Window_Hashable
from modules import Window_About
from modules import Window_Message
from modules import Window_FileChooser
#Window_Hashable = Window_Hashable.Window_Hashable
#Window_About = Window_About.Window_About
#Window_Message = Window_Message.Window_Message
#Window_FileChooser = Window_FileChooser.Window_FileChooser
'''
auto_loader()
except ImportError:
print "Cant import modules Window_Hashable onto script Hashable"
sys.exit(1)
def Software():
"Launch software Hashable Calculator"
WG = Window_Glade.Window_Glade()
WG.get_libgui( libgui )
WG.run()
WG.main()
#'''
if __name__ == "__main__":
for k, v in globals().items():
print k, "=", v
#'''
Software()
Ce qui lance mon appli, soit !
L'affichage de 'print modules.__all__' me retourne logiquement mon dictionnaire, soit :
['Window_Glade', 'Window_FileChooser', 'Window_Message', 'Window_About']
L'affichage de globals().items() me retourne cela :
GPollableInputStream = <class 'gio.__main__.GPollableInputStream'>
Window_About = <module 'modules.Window_About' from '/home/zou/Bureau/Hash@ble/modules/Window_About.pyc'>
__builtins__ = <module '__builtin__' (built-in)>
__file__ = Hashable.py
modules = <module 'modules' from '/home/zou/Bureau/Hash@ble/modules/__init__.pyc'>
__package__ = None
sys = <module 'sys' (built-in)>
libgui = gtkbuilder
Window_FileChooser = <module 'modules.Window_FileChooser' from '/home/zou/Bureau/Hash@ble/modules/Window_FileChooser.pyc'>
Window_Message = <module 'modules.Window_Message' from '/home/zou/Bureau/Hash@ble/modules/Window_Message.pyc'>
auto_loader = <function auto_loader at 0x2685aa0>
GInitiallyUnowned = <class 'gtk.__main__.GInitiallyUnowned'>
__name__ = __main__
GPollableOutputStream = <class 'gio.__main__.GPollableOutputStream'>
GFileDescriptorBased = <class 'gio.__main__.GFileDescriptorBased'>
os = <module 'os' from '/usr/lib/python2.7/os.pyc'>
__doc__ = None
Window_Glade = <module 'modules.Window_Glade' from '/home/zou/Bureau/Hash@ble/modules/Window_Glade.py'>
Software = <function Software at 0x2977668>
Donc j'ai bien, dans mon espace de noms, les modules correspondant au nom de clé de mon dictionnaire __all__.
L'appel à 'Window_Glade.Window_Glade()' fonctionne - puisqu'il démarre mon appli ... et que 'Window_Glade' fait bien partie de mon espace de nom global.
Ce que je n'arrive pas à comprendre, c'est le pourquoi, dans mon script Window_Glade, dans lequel j'ai ma classe, nommé du même nom, lorsque j'appelle 'Window_About', ou 'Window_Message', j'ai le droit à l'erreur suivante :
Traceback (most recent call last):
File "/home/zou/Bureau/Hash@ble/modules/Window_Glade.py", line 263, in on_btn_about
self.display_about_window()
File "/home/zou/Bureau/Hash@ble/modules/Window_Glade.py", line 155, in display_about_window
WA = Window_About.Window_About( array )
NameError: global name 'Window_About' is not defined
Pourtant, et c'est là que je n'arrive pas à comprendre, ma classe 'Window_Glade' est bien dans mon espace de noms global ; donc, quand j'appelle en son sein, une 'variable globale', je devrais pouvoir y accéder... et même si je fous 'global Window_About', j'ai toujours cette erreur 'NameError'.
J'en comprends le sens, mais pas le propos !!!
De même si j'écris, dans ma classe 'Window_Glade', ceci :
WA = modules.Window_About.Window_About( array )
J'ai le droit à ce message d'erreur NameError: global name 'modules' is not defined
"J'en perd mon latin !"
Ps : Et, SVP, ne me répondez pas RTFM... parce que je me tape plusieurs lectures sur Python, tel ici ou ici ...
Hors ligne
#2 Le 20/06/2012, à 09:20
- PengouinPdt
Re : [python] espace de nom, object global
Bon, ce propos ne déchaîne pas les foules...
Dans la cinquantaine de personnes qui m'ont lues, c'est étonnant qu'il n'y ait pas de "calé" en python, pour m'aider à appréhender...
Comme pour comprendre, qu'il faille à chaque fois réitérer dans chaque classe, l'import des modules python, même si justement ces classes sont importées en tant que modules. C'est pour moi, une certaine bizarrerie...
Hors ligne
#3 Le 20/06/2012, à 10:43
- Jules Petibidon
Re : [python] espace de nom, object global
Le problème de ta question c'est qu'il est difficile d'y répondre simplement
En python, il n'existe pas de niveau global dans le sens de PHP.
Chaque module de python ne peut accéder qu'aux éléments qu'il a défini ou importé explicitement.
Ça ne fonctionne pas comme php où si A inclut B qui inclut C, A accède à C.
Hors ligne
#4 Le 20/06/2012, à 11:06
- PengouinPdt
Re : [python] espace de nom, object global
Le problème de ta question c'est qu'il est difficile d'y répondre simplement
En python, il n'existe pas de niveau global dans le sens de PHP.
Chaque module de python ne peut accéder qu'aux éléments qu'il a défini ou importé explicitement.
Ça ne fonctionne pas comme php où si A inclut B qui inclut C, A accède à C.
C'est exactement ce que j'en comprend. Et, j'avoue que c'est perturbant...
Et, un peu énervant de devoir à chaque fois ré-écrire les différents imports, par exemple.
Mais, bon, je ferais avec... c'est un défaut, certes, mais pas bien grave, non plus
Hors ligne
#5 Le 20/06/2012, à 12:02
- Jules Petibidon
Re : [python] espace de nom, object global
Non c'est très loin d'être un défaut. Faut juste s'y habituer.
Tu donne à ton script exactement ce dont il a besoin, c'est beaucoup plus clair. Et tu écris tes modules sans te prendre la tête à propos des noms de variables ou de classe, tout étant encapsulé dans leur espace de nom.
Hors ligne