10
votes

En Python, pourquoi la liste [] est-elle automatiquement globale?

Ceci est un comportement étrange.

Essayez ceci: P>

rep_i=0
print "rep_i is" , rep_i
def test():
  global rep_i #without Global this gives error but list , dict , and others don't
  if rep_i==0:
    print "Testing Integer %s" % rep_i
    rep_i=1
  return "Done"

rep_lst=[1,2,3]
 

def test2():
  if rep_lst[0]==1:
    print "Testing List %s" % rep_lst
  return "Done"


if __name__=="__main__":
  test()
  test2()


1 commentaires

5 Réponses :


5
votes

Il vous suffit d'utiliser global si vous attribuez au nom global. Sans global , une mission crée une nouvelle locale.

Il n'y a rien de spécial sur la manière dont global s'applique à une liste- global influence simplement la résolution de la portée et du nom.


3 commentaires

C'est donc signifié que si j'apprends quelque chose à la liste, cela échouera? va essayer.


Non, ça ne va pas échouer. Ce n'est que si vous attribuez au nom global, ce qui est connu sous le nom de ré-obligation. Donc, rep_lst = [] créera une nouvelle liste et liera une nouvelle variable locale. Mais rep_lst.append () recherchera le nom rep_lst , trouvez-le dans l'espace de noms global et appelez une méthode à ce sujet.


Ainsi, la meilleure pratique consiste à mettre globalement global sur les VARS qui supposent être utilisés comme mondiaux? J'utilise toujours des listes globales sans définir le monde du tout (je ne sais jamais que cela soit nécessaire jusqu'à ce que je l'ai fait avec un entier).



15
votes

Ce n'est pas automatiquement global.

Cependant, il y a une différence entre rep_i = 1 et rep_lst [0] = 1 - l'ancien rebinte le nom rep_i , donc < Code> Global est nécessaire pour empêcher la création d'un emplacement local du même nom. Dans ce dernier cas, vous devez simplement modifier un objet global existant, trouvé par la recherche de noms régulière (modifier une liste de liste, c'est comme appeler une fonction de membre sur la liste, ce n'est pas un nom de rectification).

Pour le tester, essayez d'attribuer rep_lst = [] dans test2 (c'est-à-dire la définir sur une nouvelle liste). Sauf si vous déclarez rep_lst global , les effets ne seront pas visibles à l'extérieur test2 car un emplacement local du même nom est créé et les ombres du monde. Slot.


0 commentaires

3
votes

Si vous aviez attribué une nouvelle valeur à rep_lst code> à l'intérieur de test2 code> (non seulement à l'un de ses éléments, comme vous le feriez), cela ne fonctionnerait pas sans le Global code> drapeau. En Python, si vous n'abandonnez pas à une variable dans une fonction, il recherchera cette variable dans des étendues plus globales jusqu'à ce qu'elle le trouve.

Par exemple, dans ce segment de code, je définis la liste à la fois globalement et à l'intérieur de exemple () code>. Étant donné que la variable dans exemple () code> est plus proche de la portée exemple2 () code> que le global est, c'est ce qui sera utilisé. P>

x = ["out"]

def example():
    x = ["in"]
    def example2():
        print x # will print ["in"]


0 commentaires

5
votes

Il y a une erreur dans Python appelée Unboundlocalerror qui confond souvent les nouveaux arrivants. La chose déroutante est la suivante: futur mission fait modifie la façon dont une variable est levée.

Lorsque l'interprète voit un nom de variable pour la première fois, il a l'air d'aller à l'avance Le bloc de code de courant final, et si vous n'avez pas d'affectation nulle part dans le même bloc de code, l'interprète le considère global. Si vous le faites, cependant, il est considéré comme local, et toute référence à celle-ci avant que la mission génère un UnbountnountleLocalerError . C'est l'erreur que vous avez. C'est pourquoi vous devez déclarer global rep_i . Si vous n'avez pas attribué rep_i , vous n'auriez pas besoin de cette ligne.

En outre, cela n'a rien à voir avec le type de variable. En outre, attribuer ou ajouter un élément à la liste (que vous vouliez probablement faire, mais non) n'est pas affectation de la liste elle-même, elle appelle essentiellement une méthode sur un objet de liste, qui est différente de la mission: la mission crée une Nouvel objet (éventuellement sous un nom qui existe déjà), tout en manipulant une liste change simplement une liste existante. Vous pouvez essayer: xxx


0 commentaires

4
votes

Voici un exemple qui démontre qu'une liste de liste code> non dict code> est disponible dans un sous-programme et que le problème est, comme tout le monde dit, l'acte de Rebinding code> dans votre exemple de code d'origine:

x = 1
def test():
    y = x + 1
    print y
test()


1 commentaires

Merci beaucoup, cela explique beaucoup! +1