4. Modelo de execução¶
4.1. Estrutura de um programa¶
Um programa Python é construído a partir de blocos de código. Um bloco é um pedaço do texto do programa Python que é executado como uma unidade. A seguir estão os blocos: um módulo, um corpo de função e uma definição de classe. Cada comando digitado interativamente é um bloco. Um arquivo de script (um arquivo fornecido como entrada padrão para o interpretador ou especificado como argumento de linha de comando para o interpretador) é um bloco de código. Um comando de script (um comando especificado na linha de comando do interpretador com a opção -c
) é um bloco de código. Um módulo executado sobre um script de nível superior (como o módulo __main__
) a partir da linha de comando usando um argumento -m
também é um bloco de código. O argumento da string passado para as funções embutidas eval()
e exec()
é um bloco de código.
Um bloco de código é executado em um quadro de execução. Um quadro contém algumas informações administrativas (usadas para depuração) e determina onde e como a execução continua após a conclusão do bloco de código.
4.2. Nomeação e ligação¶
4.2.1. Ligação de nomes¶
Nomes referem-se a objetos. Os nomes são introduzidos por operações de ligação de nomes.
As seguintes construções ligam nomes: parâmetros formais para funções, instruções import
, definições de classe e função (estes ligam a classe ou nome de função no bloco de definição) e alvos que são identificadores se ocorrerem em uma atribuição, cabeçalho de laço for
ou após as
em uma instrução with
ou cláusula except
. A instrução import
na forma from ... import *
liga todos os nomes definidos no módulo importado, exceto aqueles que começam com um sublinhado. Este formulário só pode ser usado no nível do módulo.
Um alvo ocorrendo em uma instrução del
também é considerado ligado a esse propósito (embora a semântica real seja para desligar do nome).
Cada atribuição ou instrução de importação ocorre dentro de um bloco definido por uma definição de classe ou função ou no nível do módulo (o bloco de código de nível superior).
Se um nome está ligado a um bloco, é uma variável local desse bloco, a menos que declarado como nonlocal
ou global
. Se um nome está ligado a nível do módulo, é uma variável global. (As variáveis do bloco de código do módulo são locais e globais.) Se uma variável for usada em um bloco de código, mas não definida lá, é uma variável livre.
Cada ocorrência de um nome no texto do programa se refere à ligação daquele nome estabelecido pelas seguintes regras de resolução de nome.
4.2.2. Resolução de nomes¶
O escopo define a visibilidade de um nome dentro de um bloco. Se uma variável local é definida em um bloco, seu escopo inclui esse bloco. Se a definição ocorrer em um bloco de função, o escopo se estende a quaisquer blocos contidos no bloco de definição, a menos que um bloco contido introduza uma ligação diferente para o nome.
Quando um nome é usado em um bloco de código, ele é resolvido usando o escopo envolvente mais próximo. O conjunto de todos esses escopos visíveis a um bloco de código é chamado de ambiente do bloco.
Quando um nome não é encontrado, uma exceção NameError
é levantada. Se o escopo atual for um escopo de função e o nome se referir a uma variável local que ainda não foi associada a um valor no ponto onde o nome é usado, uma exceção UnboundLocalError
é levantada. UnboundLocalError
é uma subclasse de NameError
.
Se uma operação de ligação de nome ocorrer em qualquer lugar dentro de um bloco de código, todos os usos do nome dentro do bloco serão tratados como referências ao bloco atual. Isso pode levar a erros quando um nome é usado em um bloco antes de ser ligado. Essa regra é sutil. O Python não possui declarações e permite que as operações de ligação de nomes ocorram em qualquer lugar dentro de um bloco de código. As variáveis locais de um bloco de código podem ser determinadas varrendo todo o texto do bloco para operações de ligação de nomes.
Se a instrução global
ocorrer dentro de um bloco, todos os usos dos nomes especificados na instrução referem-se às ligações desses nomes no espaço de nomes de nível superior. Os nomes são resolvidos no espaço de nomes de nível superior pesquisando o espaço de nomes global, ou seja, o espaço de nomes do módulo que contém o bloco de código, e o espaço de nomes interno, o espaço de nomes do módulo builtins
. O espaço de nomes global é pesquisado primeiro. Se os nomes não forem encontrados lá, o espaço de nomes interno será pesquisado. A instrução global
deve preceder todos os usos dos nomes listados.
A instrução global
tem o mesmo escopo que uma operação de ligação de nome no mesmo bloco. Se o escopo mais próximo de uma variável livre contiver uma instrução global, a variável livre será tratada como global.
A instrução nonlocal
faz com que os nomes correspondentes se refiram a variáveis previamente vinculadas no escopo da função delimitadora mais próxima. A exceção SyntaxError
é levantada em tempo de compilação se o nome fornecido não existir em nenhum escopo de função delimitador.
O espaço de nomes de um módulo é criado automaticamente na primeira vez que um módulo é importado. O módulo principal de um script é sempre chamado de __main__
.
Blocos de definição de classe e argumentos para exec()
e eval()
são especiais no contexto de resolução de nomes. Uma definição de classe é uma instrução executável que pode usar e definir nomes. Essas referências seguem as regras normais para resolução de nomes, com exceção de que variáveis locais não vinculadas são pesquisadas no espaço de nomes global global. O espaço de nomes global da definição de classe se torna o dicionário de atributos da classe. O escopo dos nomes definidos em um bloco de classe é limitado ao bloco de classe; ele não se estende aos blocos de código de métodos – isso inclui compreensões e expressões geradoras, uma vez que são implementadas usando um escopo de função. Isso significa que o seguinte falhará:
class A:
a = 42
b = list(a + i for i in range(10))
4.2.3. Builtins e execução restrita¶
CPython implementation detail: Os usuários não devem tocar em __builtins__
; é estritamente um detalhe de implementação. Usuários que desejam substituir valores no espaço de nomes interno devem import
o módulo builtins
e modificar seus atributos apropriadamente.
O espaço de nomes builtins associado com a execução de um bloco de código é encontrado procurando o nome __builtins__
em seu espaço de nomes global; este deve ser um dicionário ou um módulo (no último caso, o dicionário do módulo é usado). Por padrão, quando no módulo __main__
, __builtins__
é o módulo embutido builtins
; quando em qualquer outro módulo, __builtins__
é um apelido para o dicionário do próprio módulo builtins
.
4.2.4. Interação com recursos dinâmicos¶
A resolução de nome de variáveis livres ocorre em tempo de execução, não em tempo de compilação. Isso significa que o código a seguir imprimirá 42:
i = 10
def f():
print(i)
i = 42
f()
As funções eval()
e exec()
não têm acesso ao ambiente completo para resolução de nome. Os nomes podem ser resolvidos nos espaços de nomes locais e globais do chamador. Variáveis livres não são resolvidas no espaço de nomes mais próximo, mas no espaço de nomes global. 1 As funções exec()
e eval()
possuem argumentos opcionais para substituir o espaço de nomes global e local. Se apenas um espaço de nomes for especificado, ele será usado para ambos.
4.3. Exceções¶
As exceções são um meio de romper o fluxo normal de controle de um bloco de código para tratar erros ou outras condições excepcionais. Uma exceção é levantada no ponto em que o erro é detectado; ele pode ser tratado pelo bloco de código circundante ou por qualquer bloco de código que invocou direta ou indiretamente o bloco de código onde ocorreu o erro.
O interpretador Python levanta uma exceção quando detecta um erro em tempo de execução (como divisão por zero). Um programa Python também pode levantar explicitamente uma exceção com a instrução raise
. Os tratadores de exceção são especificados com a instrução try
… except
. A cláusula finally
de tal declaração pode ser usada para especificar o código de limpeza que não trata a exceção, mas é executado se uma exceção ocorreu ou não no código anterior.
Python usa o modelo de “terminação” da manipulação de erros: um manipulador de exceção pode descobrir o que aconteceu e continuar a execução em um nível externo, mas não pode reparar a causa do erro e tentar novamente a operação com falha (exceto reinserindo a parte incorreta de código de cima).
Quando uma exceção não é manipulada, o interpretador encerra a execução do programa ou retorna ao seu laço principal interativo. Em ambos os casos, ele exeibe um traceback (situação da pilha de execução), exceto quando a exceção é SystemExit
.
As exceções são identificadas por instâncias de classe. A cláusula except
é selecionada dependendo da classe da instância: ela deve referenciar a classe da instância ou uma classe base não-virtual dela. A instância pode ser recebida pelo manipulador e pode conter informações adicionais sobre a condição excepcional.
Nota
As mensagens de exceção não fazem parte da API do Python. Seu conteúdo pode mudar de uma versão do Python para outra sem aviso e não deve ser invocado pelo código que será executado em várias versões do interpretador.
Veja também a descrição da declaração try
na seção A instrução try e a instrução raise
na seção A instrução raise.
Notas de rodapé
- 1
Essa limitação ocorre porque o código executado por essas operações não está disponível no momento em que o módulo é compilado.