J'ai ça :
g_c = 0
class TestClass():
global g_c
def run(self):
for i in range(10):
g_c = 1
print(g_c)
t = TestClass()
t.run()
print(g_c)
comment puis-je réellement modifier ma variable globale g_c ?
J'ai ça :
g_c = 0
class TestClass():
global g_c
def run(self):
for i in range(10):
g_c = 1
print(g_c)
t = TestClass()
t.run()
print(g_c)
comment puis-je réellement modifier ma variable globale g_c ?
En le déclarant global
à l'intérieur de la fonction qui y accède :
g_c = 0
class TestClass():
def run(self):
global g_c
for i in range(10):
g_c = 1
print(g_c)
En Documentation Python dit ceci, à propos de la global
déclaration :
La déclaration globale est une déclaration qui s'applique à l'ensemble du bloc de code en cours.
Vous devez déplacer le global
dans votre fonction :
class TestClass():
def run(self):
global g_c
for i in range(10):
g_c = 1
print(g_c)
Cette instruction indique au compilateur Python que toute affectation (et tout autres actions contraignantes ) à ce nom sont de modifier la valeur dans l'espace de noms global ; par défaut, tout nom qui est assigné à un endroit quelconque d'une fonction, est placé dans l'espace de noms local. L'instruction ne s'applique qu'à la portée actuelle.
Puisque vous n'assignez jamais à g_c
en el corps de classe si vous mettez la déclaration à cet endroit, cela n'a aucun effet. Le site global
ne s'applique qu'à l'étendue dans laquelle elle est utilisée, jamais aux étendues imbriquées. Voir l'article global
documentation des relevés qui s'ouvre par :
La déclaration globale est une déclaration qui s'applique à l'ensemble du bloc de code en cours.
Les fonctions et classes imbriquées ne font pas partie du bloc de code actuel.
Je vais insérer ici l'avertissement obligatoire contre l'utilisation des globaux pour partager les changements d'état : ne le faites pas, cela rend plus difficile le raisonnement sur l'état de votre code, plus difficile les tests, plus difficile la refactorisation, etc. Si vous debe partagent un état singleton changeant (une seule valeur dans l'ensemble du programme), alors utilisez au moins un fichier de type attribut de classe :
class TestClass():
g_c = 0
def run(self):
for i in range(10):
TestClass.g_c = 1
print(TestClass.g_c) # or print(self.g_c)
t = TestClass()
t.run()
print(TestClass.g_c)
Notez que nous pouvons toujours accéder à la même valeur depuis l'extérieur, en utilisant l'espace de nom de l'utilisateur. TestClass
espace de noms.
Je comprends que l'utilisation d'une variable globale est parfois la chose la plus pratique à faire, surtout dans les cas où l'utilisation d'une classe rend la chose la plus simple beaucoup plus difficile (par exemple, multiprocessing
). J'ai rencontré le même problème avec la déclaration des variables globales et je l'ai résolu par quelques expériences.
La raison pour laquelle g_c
n'a pas été modifié par le run
au sein de votre classe est que la référence au nom global dans g_c
n'a pas été établi précisément dans le cadre de la fonction. La façon dont Python gère les déclarations globales est en fait assez délicate. La commande global g_c
a deux effets :
Conditions préalables à l'entrée de la clé "g_c"
dans le dictionnaire accessible par la fonction intégrée, globals()
. Cependant, la clé n'apparaîtra dans le dictionnaire qu'après qu'une valeur lui ait été attribuée.
(Potentiellement) modifie la façon dont Python recherche la variable g_c
dans le cadre de la méthode actuelle.
La compréhension complète de (2) est particulièrement complexe. Tout d'abord, il ne modifie que potentiellement, car si aucune affectation au nom g_c
se produit dans la méthode, Python la recherche par défaut parmi les éléments suivants globals()
. Il s'agit en fait d'une chose assez courante, comme dans le cas de la référence à l'intérieur d'une méthode de modules qui sont importés tout au début du code.
Cependant, si une commande d'affectation se produit partout au sein de la méthode, Python recherche par défaut le nom g_c
dans les variables locales. Cela est vrai même lorsqu'une référence se produit avant une affectation réelle, ce qui entraînera l'erreur classique :
UnboundLocalError: local variable 'g_c' referenced before assignment
Maintenant, si la déclaration global g_c
se produit partout dans la méthode, même après toute référence ou affectation, Python recherche par défaut le nom g_c
dans les variables globales. Toutefois, si vous vous sentez d'humeur expérimentale et que vous placez la déclaration après une référence, vous serez récompensé par un avertissement :
SyntaxWarning: name 'g_c' is used prior to global declaration
Si vous y réfléchissez, la façon dont la déclaration globale fonctionne en Python est clairement intégrée et cohérente avec le fonctionnement normal de Python. C'est juste quand vous voulez vraiment qu'une variable globale fonctionne, que la norme devient gênante.
Voici un code qui résume ce que je viens de dire (avec quelques observations supplémentaires) :
g_c = 0
print ("Initial value of g_c: " + str(g_c))
print("Variable defined outside of method automatically global? "
+ str("g_c" in globals()))
class TestClass():
def direct_print(self):
print("Directly printing g_c without declaration or modification: "
+ str(g_c))
#Without any local reference to the name
#Python defaults to search for the variable in globals()
#This of course happens for all the module names you import
def mod_without_dec(self):
g_c = 1
#A local assignment without declaring reference to global variable
#makes Python default to access local name
print ("After mod_without_dec, local g_c=" + str(g_c))
print ("After mod_without_dec, global g_c=" + str(globals()["g_c"]))
def mod_with_late_dec(self):
g_c = 2
#Even with a late declaration, the global variable is accessed
#However, a syntax warning will be issued
global g_c
print ("After mod_with_late_dec, local g_c=" + str(g_c))
print ("After mod_with_late_dec, global g_c=" + str(globals()["g_c"]))
def mod_without_dec_error(self):
try:
print("This is g_c" + str(g_c))
except:
print("Error occured while accessing g_c")
#If you try to access g_c without declaring it global
#but within the method you also alter it at some point
#then Python will not search for the name in globals()
#!!!!!Even if the assignment command occurs later!!!!!
g_c = 3
def sound_practice(self):
global g_c
#With correct declaration within the method
#The local name g_c becomes an alias for globals()["g_c"]
g_c = 4
print("In sound_practice, the name g_c points to: " + str(g_c))
t = TestClass()
t.direct_print()
t.mod_without_dec()
t.mod_with_late_dec()
t.mod_without_dec_error()
t.sound_practice()
class flag:
## Store pseudo-global variables here
keys=False
sword=True
torch=False
## test the flag class
print('______________________')
print(flag.keys)
print(flag.sword)
print (flag.torch)
## now change the variables
flag.keys=True
flag.sword= not flag.sword
flag.torch=True
print('______________________')
print(flag.keys)
print(flag.sword)
print (flag.torch)
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.