Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

visibilité des variables entre modules

+2 votes

1) Créer un module MyModule.py avec, pour seul contenu :

def MyFunctionInModule():
    print var + " and displayed in MyFunctionInModule"

2) Puis, à la console Python, entrer ceci :

def MyFunction():
    print var + " and displayed in MyFunction"

var = "var defined in main"

# Ceci fonctionne bien (affiche la valeur de var)
MyFunction()

# Ceci aussi fonctionne bien (affiche tout aussi bien la valeur de var)
execfile("MyModule.py")
MyFunctionInModule()

# Mais ceci ne fonctionne pas (ne trouve pas la variable var)
import MyModule
MyModule.MyFunctionInModule()

3) Pourquoi y a-t-il une différence de comportement avec l'import ?

4) Que faut-il faire pour obtenir le même comportement avec l'import (si c'est possible) ?

demandé 1-Jan par Joel Daroussin
edité 14-Jan

Peux tu donner des exemples de codes complets que nous n'avons pas a réassembler nous même.

Hypotheses pour solutioner : peux initialier les variables avant la déclaration de la fonction dans le module importé ?

Le résulat me semble aussi surprenant, mais peut etre que l'interpreteur s'arrete une fois la fonction demandée importée du coup la globale n'est pas définie.

-> Ajoute des print entre les lignes tu verra ce qui est executé ou pas.

@precurz : J'ai modifié ma question pour la simplifier. J'essaie d'abord de comprendre la portée d'une variable simple. On verra plus tard pour les variables globales.

Je sais qu'il faut préférer le passage de valeur par paramètre. Mais ici j'essaie de comprendre et mon cas d'utilisation serait trop obscure à expliquer.

@bubulle : merci pour la règle LEGB. Ca m'a déjà pas mal éclairci. En revanche je ne comprends toujours pas bien quelle est la portée des variables entre modules. Quelqu'un peut-il m'aiguiller vers une bonne doc, si possible avec des schémas ?

1 Réponse

0 votes

Une information importante : la portée d'une variable globale n'est si globale que ça.
En particulier, une variable globale ne débordera jamais toute seule en dehors de son module.

De manière symétrique, quand une ligne de code utilise une variable, le nom de variable est résolu en suivant la règle LEGB : local / enclosed / global / builtin.
Les 3 premiers (local, enclosed, global) sont relatifs au module où se trouve la ligne de code considérée.

Dans ton exemple, tu as 2 espaces de nom (module) : MyModule et __main__ (pour le script).
Si on relit ton code en se demandant quel est l'intitulé complet des variables manipulées, on obtient:

  • Pour le code 1)

    • gvar2 -> MyModule.gvar2
    • gvar3 -> MyModule.gvar3
      .
  • Pour le code 2)

    • gvar1 -> __main__.gvar1
    • gvar3 -> __main__.gvar3

Si tu veux faire fonctionner ton code, tu peux arrêter de t'appuyer uniquement sur les variables globales et utiliser plus les arguments des fonctions.

répondu 12-Jan par bubulle (2,222 points)
...