Ce message est un peu long, avec de nombreux exemples, mais j'espère que c' va m'aider et aider les autres à mieux comprendre l'histoire complète de variables et l'attribut de recherche en Python 2.7.
Je suis en utilisant les termes de PEP 227 (http://www.python.org/dev/peps/pep-0227/) pour les blocs de code (comme les modules, la définition de la classe, des définitions de fonction, etc.) et variable liaisons (affectations, par exemple, l'argument de déclarations, de classe et la déclaration de la fonction, pour les boucles, etc.)
Je suis en utilisant les termes de variables pour les noms qui peuvent être appelées sans dot, des attributs et des noms qui ont besoin d'être qualifié avec un objet nom (obj.x pour l'attribut x de l'objet obj).
Il y a trois champs d'application dans Python pour tous les blocs de code, mais les fonctions:
- Local
- Mondial
- Builtin
Il y a quatre blocs en Python pour les fonctions uniquement (selon PEP 227):
- Local
- En joignant les fonctions
- Mondial
- Builtin
La règle pour une variable à lier et à trouver dans un bloc est très simple:
- toute liaison d'une variable à un objet dans un bloc fait de cette variable locales à ce bloc, à moins que la variable est déclarée global (dans ce cas de la variable appartient à la portée globale)
- une référence à une variable est recherché à l'aide de la règle LGB (local, global, intégré) pour tous les blocs, mais les fonctions
- une référence à une variable est recherché à l'aide de la règle LEGB (local, joignant, global, intégré) pour les fonctions.
Laissez-moi savoir prendre des exemples de validation de cette règle, et, montrant de nombreuses des cas particuliers. Pour chaque exemple, je vais donner ma compréhension. Merci corrigez-moi si je me trompe. Pour le dernier exemple, je ne comprends pas l' résultat.
exemple 1:
x = "x in module"
class A():
print "A: " + x #x in module
x = "x in class A"
print locals()
class B():
print "B: " + x #x in module
x = "x in class B"
print locals()
def f(self):
print "f: " + x #x in module
self.x = "self.x in f"
print x, self.x
print locals()
>>>A.B().f()
A: x in module
{'x': 'x in class A', '__module__': '__main__'}
B: x in module
{'x': 'x in class B', '__module__': '__main__'}
f: x in module
x in module self.x in f
{'self': <__main__.B instance at 0x00000000026FC9C8>}
Il n'est pas imbriquée portée pour les classes (règle LGB) et une fonction dans une classe ne peut pas accéder aux attributs de la classe sans l'aide d'un nom complet (du soi.x dans cet exemple). C'est bien décrite dans PEP227.
exemple 2:
z = "z in module"
def f():
z = "z in f()"
class C():
z = "z in C"
def g(self):
print z
print C.z
C().g()
f()
>>>
z in f()
z in C
Ici les variables dans les fonctions de recherche à l'aide de la LEGB la règle, mais si une classe est le chemin, la classe arguments sont ignorés. Ici encore, c'est ce que PEP 227, c'est d'expliquer.
exemple 3:
var = 0
def func():
print var
var = 1
>>> func()
Traceback (most recent call last):
File "<pyshell#102>", line 1, in <module>
func()
File "C:/Users/aa/Desktop/test2.py", line 25, in func
print var
UnboundLocalError: local variable 'var' referenced before assignment
Nous attendons avec un langage dynamique comme le python que tout est résolu dynamiquement. Mais ce n'est pas le cas pour les fonctions. Local les variables sont déterminées au moment de la compilation. PEP 227 et http://docs.python.org/2.7/reference/executionmodel.html décrire cette le comportement de cette façon
"Si un nom de liaison opération se produit n'importe où à l'intérieur d'un bloc de code, tous les les utilisations de ce nom dans le bloc sont traités comme des références à la bloc courant."
exemple 4:
x = "x in module"
class A():
print "A: " + x
x = "x in A"
print "A: " + x
print locals()
del x
print locals()
print "A: " + x
>>>
A: x in module
A: x in A
{'x': 'x in A', '__module__': '__main__'}
{'__module__': '__main__'}
A: x in module
Mais nous voyons ici que cette déclaration dans PEP227 "Si un nom de liaison l'opération se produit n'importe où à l'intérieur d'un bloc de code, toutes les utilisations de ce nom dans le bloc sont traités comme des références pour le bloc en cours." le problème quand le bloc de code est une classe. En outre, pour les classes, il semble que le nom local de la liaison n'est pas faite au moment de la compilation, mais au cours de exécution à l'aide de la classe de l'espace de noms. À cet égard, PEP227 et le modèle d'exécution dans la doc Python est trompeuse et pour certaines parties de mal.
exemple 5:
x = 'x in module'
def f2():
x = 'x in f2'
def myfunc():
x = 'x in myfunc'
class MyClass(object):
x = x
print x
return MyClass
myfunc()
f2()
>>>
x in module
ma compréhension de ce code est le suivant. L'instruction x = x regardez d'abord l'objet de la main droite x de l'expression se réfère . Dans ce cas, l'objet est recherché localement dans la classe, suivant la règle LGB il est recherché dans le contexte global, qui est la chaîne de caractères 'x dans le module'. Ensuite, un local de l'attribut x de MyClass est créée dans la classe dictionnaire et a souligné l'objet de type string.
exemple 6:
Maintenant ici est un exemple je ne peux pas expliquer. Il est très proche de l'exemple 5, je suis simplement en changeant le local MyClass attribut de x à y.
x = 'x in module'
def f2():
x = 'x in f2'
def myfunc():
x = 'x in myfunc'
class MyClass(object):
y = x
print y
return MyClass
myfunc()
f2()
>>>
x in myfunc
Pourquoi, dans ce cas, le x de référence dans Maclasse est recherché dans le fonction la plus intérieure?