Não estou perguntando sobre as regras de escopo do Python; Geralmente eu entendo como o escopo funciona em Python para loops. Minha pergunta é por que as decisões de design foram tomadas dessa maneira. Por exemplo (sem trocadilhos):
for foo in xrange(10):
bar = 2
print(foo, bar)
O acima será impresso (9,2).
Isso me parece estranho: 'foo' está realmente apenas controlando o loop, e 'bar' foi definido dentro do loop. Entendo por que pode ser necessário que 'bar' seja acessível fora do loop (caso contrário, os loops teriam funcionalidade muito limitada). O que não entendo é por que é necessário que a variável de controle permaneça no escopo após a saída do loop. Na minha experiência, ele simplesmente atravessa o espaço para nome global e dificulta a detecção de erros que seriam detectados por intérpretes em outros idiomas.
for
loop atravesse seu namespace global, envolva-o em uma função. Encerramentos em abundância!Respostas:
A resposta mais provável é que ela mantém a gramática simples, não foi um obstáculo para a adoção e muitos ficaram felizes por não ter de desambiguar o escopo ao qual um nome pertence ao atribuí-lo em uma construção de loop. As variáveis não são declaradas dentro de um escopo, elas estão implícitas na localização das instruções de atribuição. A
global
palavra-chave existe apenas por esse motivo (para indicar que a atribuição é feita em um escopo global).Atualizar
Aqui está uma boa discussão sobre o tópico: http://mail.python.org/pipermail/python-ideas/2008-October/002109.html
Em suma, você provavelmente pode culpar a comunidade Python: P
fonte
O Python não possui blocos, assim como algumas outras linguagens (como C / C ++ ou Java). Portanto, a unidade de escopo no Python é uma função.
fonte
for
loops de escopo são uma extensão natural de um princípio geral. No Python, teria que ser um caso especial, e casos especiais devem ser evitados, a menos que tenham benefícios atraentes.Um caso realmente útil para isso é quando
enumerate
você usa e deseja a contagem total no final:Isso é necessário? Não. Mas, com certeza é conveniente.
Outra coisa a ter em atenção: no Python 2, as variáveis nas compreensões de lista também são vazadas:
Mas, o mesmo não se aplica ao Python 3.
fonte
else
cláusula, ie.else: print "I did something {0} times".format(count)
- antes que o escopo local (que não existe no Python) desapareçasomeiterator
estiver vazio?else
cláusula possa ser usada neste caso, ela não funcionaria em geral, já que o corpo do loop poderiabreak
prematuramente.Se você tiver uma instrução break no loop (e quiser usar o valor da iteração posteriormente, talvez para recuperar, indexar algo ou dar status), ela economizará uma linha de código e uma atribuição, para que haja uma conveniência.
fonte
Uma das principais influências do Python é o ABC , uma linguagem desenvolvida na Holanda para ensinar conceitos de programação para iniciantes. O criador de Python, Guido van Rossum, trabalhou no ABC por vários anos nos anos 80. Não sei quase nada sobre o ABC, mas como ele é destinado a iniciantes, suponho que ele deva ter um número limitado de escopos, bem como os primeiros BASICs.
fonte
Para iniciantes, se as variáveis fossem locais para loops, esses loops seriam inúteis para a maioria das programações do mundo real.
Na situação atual:
rendimentos
45
. Agora, considere como a atribuição funciona no Python. Se as variáveis de loop fossem estritamente locais:produz
0
, porquetotal
dentro do loop após a atribuição não é a mesma variável quetotal
fora do loop. Esse não seria um comportamento ideal ou esperado.fonte
total
efoo
ainda teria ligações locais de loop no cenário do OP e a lógica é a mesma.