Motivo do comportamento não-intencional do UnboundLocalError

Nota: Existe uma questão muito semelhanteAqui. Fique comigo, no entanto; minha pergunta não é "Por que o erro acontece", mas "Por que o Python foi implementado para lançar um erro neste caso".

Eu apenas tropecei nisso:

a = 5
def x()
    print a
    a = 6
x()

lança umUnboundLocalException. Agora, eu sei porque isso acontece (mais tarde neste escopo,a está ligado, entãoa é considerado local em todo o escopo).

Nesse caso:

a = 5
def x()
    print b
    b = 6
x()

isso faz muito sentido. Mas o primeiro caso tem uma lógica intuitiva, que significa isso:

a = 5
def x()
    print globals()["a"]
    a = 6 # local assignment
x()

Eu acho que há uma razão pela qual a versão "intuitiva" não é permitida, mas o que é isso? Embora isso possa ser um caso de "Explícito é melhor do que implícito", brincando com oglobals() sempre me parece um pouco impuro.

Para colocar isso em perspectiva, o caso real em que isso aconteceu comigo foi o script de outra pessoa que tive que mudar por um momento. Na minha mudança (de curta duração), eu fiz alguns renomear arquivos enquanto o script estava rodando, então eu inseri

import os
os.rename("foo", "bar")

no script. Esta inserção aconteceu dentro de uma função. O módulo já importadoos no nível superior (eu não verifiquei isso), e algunsos.somefunction chama onde feito dentro da função, mas antes da minha inserção. Essas chamadas obviamente desencadearamUnboundLocalException.

Então, alguém pode explicar o raciocínio por trás dessa implementação para mim? É para evitar que o usuário cometa erros? A maneira "intuitiva" apenas tornaria as coisas mais complicadas para o compilador bytecode? Ou existe uma ambiguidade possível que eu não pensei?

questionAnswers(3)

yourAnswerToTheQuestion