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?