¿Por qué la asignación no activada cambió el comportamiento `no local`?

Hoy estoy leyendo el registro de cambios de Python y conozco la palabra clave no local e hice algunos experimentos con ella. Encuentro una situación confusa donde la asignación no activada cambiará el comportamiento de las palabras clave nonlocal , consulte el siguiente ejemplo.

 def a(): x = 'a' def b(): def c(): nonlocal x x = 'c' c() b() print(x) a() >>> python3 test.py c def a(): x = 'a' def b(): def c(): nonlocal x x = 'c' c() if False: x = 'b' b() print(x) a() >>> python3 test2.py a 

Se puede ver que en test2.py , hay una asignación no activada x = 'b' que cambió el comportamiento de nonlocal.

¿Por qué sucedió esto?

Python decide qué variables son locales a una función en tiempo de comstackción . x se asigna a dentro de la función b , por lo que es local. Que esa twig nunca se scope en el tiempo de ejecución es irrelevante y no se puede decidir en general.

Entonces, la x en c que no es local es la siguiente x en un ámbito externo, es decir, la que está en b .

La alternativa sería mucho más sorprendente: considere qué pasaría si el if False: si if False: if rand(10) == 6: Luego, durante la primera llamada de b la variable no local se referiría a la más externa, pero al azar en una llamada posterior de b , ¡comenzaría a referirse a la otra!