Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 18/06/2012, à 15: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 !" tongue

Ps : Et, SVP, ne me répondez pas RTFM... parce que je me tape plusieurs lectures sur Python, tel ici ou ici ...


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#2 Le 20/06/2012, à 10: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...


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#3 Le 20/06/2012, à 11: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 smile

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, à 12:06

PengouinPdt

Re : [python] espace de nom, object global

Jules Petibidon a écrit :

Le problème de ta question c'est qu'il est difficile d'y répondre simplement smile

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 tongue


Ego ~
YUP.py :: Yet Uploader Pixxie.py :: script python : post d'images sur forum !

Hors ligne

#5 Le 20/06/2012, à 13: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