Lorsque je regardais l'implémentation de la fermeture, je ne savais pas pourquoi cela fonctionnait, alors j'ai regardé à quoi ressemble la portée. Je pense que c'est très basique, mais je n'ai pas trouvé d'article sur le net qui pourrait comprendre à quoi ressemble la lunette. À la suite de l'avoir déplacé, j'ai pensé que c'était difficile à expliquer.
Vérifions l'état des variables globales et locales avec le code suivant.
from pprint import pprint
print "-----globals----->>>"
pprint(globals())
print "-----locals----->>>"
pprint(locals())
Résultat d'exécution
-----globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'pprint': <function pprint at 0x02222770>}
-----locals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'pprint': <function pprint at 0x02222770>}
Dans cet état, le contenu affiché pour les variables globales et locales est le même. Que se passe-t-il si vous définissez une variable?
from pprint import pprint
a = 123
pprint(globals())
print "-----globals----->>>"
print "-----locals----->>>"
pprint(locals())
Résultat d'exécution
-----globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>}
-----locals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>}
Dans l'environnement d'exécution de script de niveau supérieur, le contenu de sortie de locals () et globals () est le même. Les variables définies sont présentes dans les deux sorties. (*** Globals () et local () sont jugés pour afficher les noms de la portée globale et de la portée locale, respectivement, et ce qui suit est décrit **)
De plus, pprint est dans la sortie de globals (). (aussi dans les locaux ()) Les modules et fonctions importés par import seront inclus dans la portée globale. (Ceux qui peuvent être directement référencés au niveau supérieur sont dans la portée globale)
Que se passe-t-il si vous définissez une fonction et regardez la portée à partir de la fonction?
##Vérification(3)
a = 123
def tes001():
b = 234
print "-----globals----->>>"
pprint(globals())
print "-----locals----->>>"
pprint(locals())
tes001()
Résultat d'exécution
-----globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02422770>,
'tes001': <function tes001 at 0x02422BF0>}
-----locals----->>>
{'b': 234}
La variable b définie dans le bloc fonction existe dans la portée locale mais pas dans la portée globale.
Définissons maintenant les variables après avoir affiché le contenu de locals () et globals () dans le bloc fonction.
a = 123
def tes001():
print "-----globals----->>>"
pprint(globals())
print "-----locals----->>>"
pprint(locals())
b = 234
tes001()
Résultat d'exécution
-----globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>,
'tes001': <function tes001 at 0x02222BF0>}
-----locals----->>>
{}
Dans ce cas, la variable b n'est pas non plus dans la portée locale. Que se passe-t-il si vous placez la sortie de locals () avant et après la définition de variable?
a = 123
def tes001():
print "-----globals----->>>"
pprint(globals())
print "-----locals(1)----->>>"
pprint(locals())
b = 234
print "-----locals(2)----->>>"
pprint(locals())
tes001()
Résultat d'exécution
-----globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>,
'tes001': <function tes001 at 0x02222BF0>}
-----locals(1)----->>>
{}
-----locals(2)----->>>
{'b': 234}
C'est comme prévu. Il n'est pas dans la sortie avant que la variable ne soit définie, mais dans la sortie après sa définition.
Ensuite, imbriquez les définitions de fonction et vérifiez la portée à partir de la fonction interne.
a = 123
def tes001():
b = 234
def inner():
c = 345
print "-----globals----->>>"
pprint(globals())
print "-----locals----->>>"
pprint(locals())
inner()
tes001()
Résultat d'exécution
-----globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x022226F0>,
'tes001': <function tes001 at 0x02222BF0>}
-----locals----->>>
{'c': 345}
Il n'y a pas de b dans la portée locale de inner (). Que se passe-t-il si vous faites référence à b dans inner ()? Affichez la sortie des sections locales () avant et après le référencement.
a = 123
def tes001():
b = 234
def inner():
c = 345
print "-----globals----->>>"
pprint(globals())
print "-----locals(1)----->>>"
pprint(locals())
print b
print "-----locals(2)----->>>"
pprint(locals())
inner()
tes001()
Résultat d'exécution
-----globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x022226F0>,
'tes001': <function tes001 at 0x02222BF0>}
-----locals(1)----->>>
{'b': 234, 'c': 345}
234
-----locals(2)----->>>
{'b': 234, 'c': 345}
Cette fois, la variable b existe également dans la portée locale avant de référencer la variable b (`` print b ''). Cela semble un peu différent de "confirmation (5)". Le comportement est différent entre la référence et l'affectation. Sensuellement
-----locals(1)----->>>
{'c': 345}
234
-----locals(2)----->>>
{'b': 234, 'c': 345}
Je pensais que ce serait comme ça. Le résultat ci-dessus suppose que la portée locale de la fonction inner () a une portée contenant la variable b avant d'exécuter le code. En premier lieu, la variable b est incluse dans la portée locale même si elle n'est pas définie dans la fonction inner (). Du point de vue du mouvement, lorsque la fonction est imbriquée, lorsque la fonction interne se réfère à une variable indéfinie et définie à l'extérieur, lorsque la fonction interne y fait référence, le contenu de la définition de la fonction externe est copié et la fonction interne est copiée. Définissez la portée locale de. Ce paramètre de portée semble avoir été effectué avant l'exécution du code. Il semble que la valeur initiale de la portée locale est créée avant que la fonction ne soit exécutée.
Examinons la portée lorsque la variable définie à l'extérieur est modifiée avec la fonction à l'intérieur.
a = 123
def tes001():
b = 234
def inner():
c = 345
print "-----inner: globals----->>>"
pprint(globals())
print "-----inner: locals(1)----->>>"
pprint(locals())
print b
b = 777
print "-----inner: locals(2)----->>>"
pprint(locals())
inner()
print "-----outer: locals(3)----->>>"
pprint(locals())
tes001()
Résultat d'exécution
-----inner: globals----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes002.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x022226F0>,
'tes001': <function tes001 at 0x02222BF0>}
-----inner: locals(1)----->>>
{'c': 345}
Traceback (most recent call last):
File "tes002.py", line 19, in <module>
tes001()
File "tes002.py", line 16, in tes001
inner()
File "tes002.py", line 12, in inner
print b
UnboundLocalError: local variable 'b' referenced before assignment
Après avoir exécuté ce qui précède, j'ai eu une erreur (Erreur locale non liée).
Fait intéressant, le contenu de locals (), qui est d'abord généré par la fonction inner (), n'inclut pas la variable b.
Si seule la référence ( print b '') était faite, b était inclus. La seule différence est de savoir si la fonction interne définit les variables définies sur l'extérieur. Après tout, il semble que la portée soit préparée avant d'exécuter le code. Le code fonctionne sur la base de cette portée préparée. Cependant, dans l'exemple ci-dessus, la variable b n'est pas définie dans la portée locale préparée au moment de l'exécution car il existe un code de réglage (
b = 777 '') dans la fonction interne.
Dans cet état (la variable b n'est pas dans la portée), une erreur se produit en essayant de faire référence à la variable b.
Si vous organisez le contenu confirmé jusqu'à présent, y compris certaines inférences (spéculation),
Ensuite, examinons à quoi ressemble la portée lorsque la variable globale est référencée et définie dans la fonction.
a = 123
def tes001():
print a
print "-----tes001: globals(1)----->>>"
pprint(globals())
print "-----tes001: locals(1)----->>>"
pprint(locals())
a = 345
print "-----tes001: globals(2)----->>>"
pprint(globals())
print "-----tes001: locals(2)----->>>"
pprint(locals())
tes001()
print "-----top: globals(3)----->>>"
pprint(globals())
print "-----top: locals(3)----->>>"
pprint(locals())
Résultat d'exécution
Traceback (most recent call last):
File "tes003.py", line 15, in <module>
tes001()
File "tes003.py", line 5, in tes001
print a
UnboundLocalError: local variable 'a' referenced before assignment
Dans ce cas, identique à la confirmation (7). UnboundLocalError. Le même comportement lorsque l'étendue globale et l'étendue locale sont mélangées. Dans la fonction tes001 (), attribuer la variable a puis la référencer devrait fonctionner.
a = 123
def tes001():
print "-----tes001: globals(1)----->>>"
pprint(globals())
print "-----tes001: locals(1)----->>>"
pprint(locals())
a = 345
print a
print "-----tes001: globals(2)----->>>"
pprint(globals())
print "-----tes001: locals(2)----->>>"
pprint(locals())
tes001()
print "-----top: globals(3)----->>>"
pprint(globals())
print "-----top: locals(3)----->>>"
pprint(locals())
Résultat d'exécution
-----tes001: globals(1)----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes003.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>,
'tes001': <function tes001 at 0x02222BB0>}
-----tes001: locals(1)----->>>
{}
345
-----tes001: globals(2)----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes003.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>,
'tes001': <function tes001 at 0x02222BB0>}
-----tes001: locals(2)----->>>
{'a': 345}
-----top: globals(3)----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes003.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>,
'tes001': <function tes001 at 0x02222BB0>}
-----top: locals(3)----->>>
{'__builtins__': <module '__builtin__' (built-in)>,
'__doc__': None,
'__file__': 'tes003.py',
'__name__': '__main__',
'__package__': None,
'a': 123,
'pprint': <function pprint at 0x02222770>,
'tes001': <function tes001 at 0x02222BB0>}
Cela a bien fonctionné. Dans la sortie de tes001: globals (2), a vaut 123 et dans la sortie de tes001: locals (2) 345. Dans tes001 (), la variable locale a est réécrite, donc la valeur de a lors du retour au niveau supérieur reste la valeur (123) avant l'appel de la fonction. J'ai en quelque sorte compris la théorie, mais cela me semble un peu étrange. Supprimez l'instruction d'impression et essayez d'organiser le code quand cela fonctionne et quand cela ne fonctionne pas.
a = 123
def tes001():
print a
tes001()
a = 123
def tes001():
a = 345
print a
tes001()
a = 123
def tes001():
print a #UnboundLocalError
a = 345
tes001()
J'ai fait divers mouvements et donné les raisons des résultats de l'opération, mais en regardant ce qui précède, c'est encore difficile à comprendre. J'aimerais enquêter un peu plus, mais ça s'allonge, alors je vais m'arrêter ici. Je pense que je peux expliquer la mise en œuvre des fermetures.
Recommended Posts