web-dev-qa-db-fra.com

avertissement de variable globale dans python

J'ai un script python 2.6 (oui je sais que je devrais passer à au moins 2.7) qui ressemble à ceci:

ret_code = 0

def some_func()
  global ret_code
  ...

if __== '__main__':
  global ret_code
  ...

Maintenant, je reçois un avertissement si j'exécute le code: * SyntaxWarning: le nom 'ret_code' est affecté à avant la déclaration globale global ret_code *

Pourquoi ai-je cet avertissement?

Je peux résoudre le problème en procédant ainsi:

def some_func()
      global ret_code
      ...

if __== '__main__':
  global ret_code
  ret_code = 0 #assign 0 here instead of above
  ...

Cela ne répond toujours pas à ma question. Quel est le problème avec le code d'origine?

43
whomaniac

La meilleure façon directe de résoudre ce problème consiste à supprimer la déclaration global sous if __== '__main__':. Vous n'en avez pas besoin là-bas. Contrairement à d'autres langages, une instruction if n'introduit pas de nouvelle portée dans Python - toutes les variables que vous affectez dans ce bloc sont globales, tout comme elles le seraient sans le if là-bas.

Cela explique également pourquoi il s'agit d'une erreur: pour déclarer une variable en tant que global, vous n'êtes pas autorisé à avoir utilisé ce nom de variable auparavant dans la même portée (probablement parce que cela serait source de confusion pour le global instruction pour effectuer des affectations avant il va à la variable globale, et Python ne prend pas en charge le même nom étant à la fois global et local dans la même étendue). if n'introduit pas de nouvelle étendue, la première affectation à ret_code est dans la même étendue que la déclaration globale sous if; mais la déclaration globale vient plus tard que l'affectation, qui n'est pas autorisée.

Pour une solution encore meilleure, demandez-vous si vous pouvez supprimer complètement l'état global mutable de votre programme, car il provoque généralement plus de problèmes que sa valeur quelque part plus tard. Ici, il semble probable que vous utilisez ret_code Comme code de sortie de programme - c'est-à-dire que vous ferez sys.exit(ret_code) quelque part - mais vous décidez à l'intérieur d'une fonction quel code de sortie pour utilisation. À la place, transmettez suffisamment d'informations au code de niveau supérieur pour it pour décider du code de sortie à utiliser.

91
lvc