Pour moi le fait que la lecture d'une variable et son écriture se comportent différemment du point de vue de la portée n'a pas de sens (à part "c'est une erreur qui date d'il y a longtemps et on ne pouvait pas la corriger sans risquer de casser du code"), c'est un défaut du langage. Un débutant n'a pas de raison de comprendre pourquoi ça marche dans un cas et pas dans l'autre, et n'a aucune chance de deviner tout seul qu'il faut utiliser nonlocal—en fait personne ne connaît cette fonctionnalité ou presque. C'est un cas typique d'erreur de conception.
Imagine que tu as écris:
deff():x=1print(x)
maintenant pour une raison ou une autre, tu veux mettre la dernière ligne de code dans une fonction auxiliaire (et l'appeler pour conserver le même comportement):
deff():x=1defg():print(x)g()
Ça marche très bien, ça fait la même chose. Mais pendant ce temps ton collègue a fait un commit dans son coin, et il a rajouté deux lignes à la fonction de départ:
deff():x=1print(x)x=2print(x)
Pas de soucis, tu règles le conflit de merge en rajoutant ces lignes dans ta fonction:
deff():x=1defg():print(x)x=2printxg()
Et là tu as une erreur UnboundLocalError! Incompréhensible.
[^] # Re: portée lexicale ?
Posté par gasche . En réponse au message De la conception du langage Python. Évalué à 9.
Pour moi le fait que la lecture d'une variable et son écriture se comportent différemment du point de vue de la portée n'a pas de sens (à part "c'est une erreur qui date d'il y a longtemps et on ne pouvait pas la corriger sans risquer de casser du code"), c'est un défaut du langage. Un débutant n'a pas de raison de comprendre pourquoi ça marche dans un cas et pas dans l'autre, et n'a aucune chance de deviner tout seul qu'il faut utiliser
nonlocal—en fait personne ne connaît cette fonctionnalité ou presque. C'est un cas typique d'erreur de conception.Imagine que tu as écris:
maintenant pour une raison ou une autre, tu veux mettre la dernière ligne de code dans une fonction auxiliaire (et l'appeler pour conserver le même comportement):
Ça marche très bien, ça fait la même chose. Mais pendant ce temps ton collègue a fait un commit dans son coin, et il a rajouté deux lignes à la fonction de départ:
Pas de soucis, tu règles le conflit de merge en rajoutant ces lignes dans ta fonction:
Et là tu as une erreur
UnboundLocalError! Incompréhensible.