3. Modelo de dados

3.1. Objetos, valores e tipos

Objetos são abstrações do Python para dados. Todo dados em um programa Python, é representados por objetos ou por relações entre objetos.(De certo modo, e em conformidade com o modelo de Von Neumann em “stored program computer,” código também é representado por objetos.)

Todo objeto tem uma identidade, um tipo e um valor. A *identidade de um objeto, nunca muda depois de criado; você pode pensar nisso como endereço de objetos em memória. O operador ‘: keyword: is’ compara as identidades de dois objetos; a função id() retorna um inteiro representando sua identidade.

CPython implementation detail: Para CPython, id(x) é o endereço de memória em que x é armazenado.

O tipo de um objeto determina as operações que o objeto suporta (por exemplo, “ele tem um comprimento?”) e também define os valores possíveis para objetos desse tipo. A função type() retorna o tipo de um objeto (que é o próprio objeto). Como sua identidade, o objeto: dfn: type também é imutável. [#] _

O valor de alguns objetos pode mudar. Objetos cujos valores podem mudar são descritos como mutáveis, objetos cujo valor não pode ser mudado uma vez que foram criados são chamados imutáveis. (O valor de uma coleção que contém uma referência a um objeto mutável pode mudar quando o valor deste último for mudado; no entanto a coleção é ainda assim considerada imutável, pois a coleção de objetos que contém não pode ser mudada. Então a imutabilidade não é estritamente o mesmo do que não haver mudanças de valor, é mais sutil.) A mutabilidade de um objeto é determinada pelo seu tipo; por exemplo, números, strings e tuplas são imutáveis, enquanto dicionários e listas são mutáveis.

Os objetos nunca são destruídos explicitamente; no entanto, quando eles se tornam inacessíveis, eles podem ser coletados como lixo. Uma implementação tem permissão para adiar a coleta de lixo ou omiti-la completamente – é uma questão de qualidade de implementação como a coleta de lixo é implementada, desde que nenhum objeto seja coletado que ainda esteja acessível.

CPython implementation detail: CPython atualmente usa um esquema de contagem de referência com detecção atrasada (opcional) de lixo ligado ciclicamente, que coleta a maioria dos objetos assim que eles se tornam inacessíveis, mas não é garantido que coletará lixo contendo referências circulares. Veja a documentação do módulo gc para informações sobre como controlar a coleta de lixo cíclico. Outras implementações agem de forma diferente e o CPython pode mudar. Não dependa da finalização imediata dos objetos quando eles se tornarem inacessíveis (portanto, você deve sempre fechar os arquivos explicitamente).

Observe que o uso dos recursos de rastreamento ou depuração da implementação pode manter os objetos ativos que normalmente seriam coletáveis. Observe também que capturar uma exceção com uma instrução “tryexcept” pode manter os objetos vivos.

Alguns objetos contêm referências a recursos “externos”, como arquivos abertos ou janelas. Entende-se que esses recursos são liberados quando o objeto é coletado como lixo, mas como a coleta de lixo não é garantida, tais objetos também fornecem uma maneira explícita de liberar o recurso externo, geralmente um método close(). Os programas são fortemente recomendados para fechar explicitamente esses objetos. A instrução “tryfinally” e a instrução “with” fornecem maneiras convenientes de fazer isso.

Alguns objetos contêm referências a outros objetos; eles são chamados de contêineres. Exemplos de contêineres são tuplas, listas e dicionários. As referências fazem parte do valor de um contêiner. Na maioria dos casos, quando falamos sobre o valor de um contêiner, nos referimos aos valores, não às identidades dos objetos contidos; entretanto, quando falamos sobre a mutabilidade de um contêiner, apenas as identidades dos objetos contidos imediatamente estão implícitas. Portanto, se um contêiner imutável (como uma tupla) contém uma referência a um objeto mutável, seu valor muda se esse objeto mutável for alterado.

Os tipos afetam quase todos os aspectos do comportamento do objeto. Até mesmo a importância da identidade do objeto é afetada em algum sentido: para tipos imutáveis, as operações que calculam novos valores podem realmente retornar uma referência a qualquer objeto existente com o mesmo tipo e valor, enquanto para objetos mutáveis isso não é permitido. Por exemplo, após a = 1; b = 1, a e b podem ou não se referir ao mesmo objeto com o valor um, dependendo da implementação, mas após c = []; d = [], c e d têm a garantia de referir-se a duas listas vazias diferentes e únicas. (Observe que c = d = [] atribui o mesmo objeto para c e d.)

3.2. A hierarquia de tipos padrão

Abaixo está uma lista dos tipos que são embutidos no Python. Módulos de extensão (escritos em C, Java ou outras linguagens, dependendo da implementação) podem definir tipos adicionais. Versões futuras do Python podem adicionar tipos à hierarquia de tipo (por exemplo, números racionais, matrizes de inteiros armazenadas de forma eficiente, etc.), embora tais adições sejam frequentemente fornecidas por meio da biblioteca padrão.

Algumas das descrições de tipo abaixo contêm um parágrafo listando “atributos especiais”. Esses são atributos que fornecem acesso à implementação e não se destinam ao uso geral. Sua definição pode mudar no futuro.

None

Este tipo possui um único valor. Existe um único objeto com este valor. Este objeto é acessado através do nome embutido None. É usado para significar a ausência de um valor em muitas situações, por exemplo, ele é retornado de funções que não retornam nada explicitamente. Seu valor de verdade é falso.

NotImplemented

This type has a single value. There is a single object with this value. This object is accessed through the built-in name NotImplemented. Numeric methods and rich comparison methods should return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.) Its truth value is true.

Veja a documentação Implementing the arithmetic operations para mais detalhes.;

Ellipsis

Este tipo possui um único valor. Existe um único objeto com este valor. Este objeto é acessado através do literal ... ou do nome embutido Ellipsis (reticências). Seu valor de verdade é true.

numbers.Number

Eles são criados por literais numéricos e retornados como resultados por operadores aritméticos e funções aritméticas integradas. Os objetos numéricos são imutáveis; uma vez criado, seu valor nunca muda. Os números do Python são, obviamente, fortemente relacionados aos números matemáticos, mas sujeitos às limitações da representação numérica em computadores.

Python distingue entre inteiros, números de ponto flutuante e números complexos:

numbers.Integral

Estes representam elementos do conjunto matemático de inteiros (positivos e negativos).

Existem dois tipos de inteiros:

Integers (int)

Eles representam números em um intervalo ilimitado, sujeito apenas à memória (virtual) disponível. Para o propósito de operações de deslocamento e máscara, uma representação binária é assumida e os números negativos são representados em uma variante do complemento de 2 que dá a ilusão de uma string infinita de bits de sinal estendendo-se para a esquerda.

Booleans (bool)

Estes representam os valores da verdade Falsos e Verdadeiros. Os dois objetos que representam os valores False e True são os únicos objetos booleanos. O tipo booleano é um subtipo do tipo inteiro, e os valores booleanos se comportam como os valores 0 e 1, respectivamente, em quase todos os contextos, com exceção de que, quando convertidos em uma string, as strings "False" ou "True" são retornados, respectivamente.

As regras para representação de inteiros têm como objetivo fornecer a interpretação mais significativa das operações de deslocamento e máscara envolvendo inteiros negativos.

numbers.Real (float)

Eles representam números de ponto flutuante de precisão dupla no nível da máquina. Você está à mercê da arquitetura da máquina subjacente (e implementação C ou Java) para o intervalo aceito e tratamento de estouro. Python não oferece suporte a números de ponto flutuante de precisão única; a economia no uso do processador e da memória, que normalmente é o motivo de usá-los, é ofuscada pela sobrecarga do uso de objetos em Python, portanto, não há razão para complicar a linguagem com dois tipos de números de ponto flutuante.

numbers.Complex (complex)

Eles representam números complexos como um par de números de ponto flutuante de precisão dupla no nível da máquina. As mesmas advertências se aplicam aos números de ponto flutuante. As partes reais e imaginárias de um número complexo z podem ser recuperadas através dos atributos somente leitura z.real e z.imag.

Sequências

Eles representam conjuntos ordenados finitos indexados por números não negativos. A função embutida len() retorna o número de itens de uma sequência. Quando o comprimento de uma sequência é n, o conjunto de índices contém os números 0, 1, …, n-1. O item i da sequência a é selecionado por a[i].

Sequências também suportam fatiamento: a[i:j] seleciona todos os itens com índice k de forma que i <= k < j. Quando usada como expressão, uma fatia é uma sequência do mesmo tipo. Isso implica que o conjunto de índices é renumerado para que comece em 0.

Algumas sequências também suportam “fatiamento estendido” com um terceiro parâmetro de “etapa”: a[i:j:k] seleciona todos os itens de a com índice x onde x = i + n*k, n >= 0 e i <= x < j.

As sequências são distinguidas de acordo com sua mutabilidade:

Sequências Imutáveis

Um objeto de um tipo de sequência imutável não pode ser alterado depois de criado. (Se o objeto contiver referências a outros objetos, esses outros objetos podem ser mutáveis e podem ser alterados; no entanto, a coleção de objetos diretamente referenciada por um objeto imutável não pode ser alterada.)

Os tipos a seguir são sequências imutáveis:

Strings

Uma string é uma sequência de valores que representam pontos de código Unicode. Todos os pontos de código no intervalo U+0000 - U+10FFFF podem ser representados em uma string. Python não tem um tipo char; em vez disso, cada ponto de código na string é representado como um objeto string com comprimento 1. A função embutida ord() converte um ponto de código de sua forma de string para um inteiro no intervalo 0 - 10FFFF; chr() converte um inteiro no intervalo 0 - 10FFFF para o comprimento correspondente do objeto de string 1. str.encode() pode ser usado para converter uma str para bytes usando a codificação de texto fornecida, e bytes.decode() pode ser usado para conseguir o oposto.

Tuplas

Os itens de uma tupla são objetos Python arbitrários. Tuplas de dois ou mais itens são formadas por listas de expressões separadas por vírgulas. Uma tupla de um item (um “singleton”) pode ser formada afixando uma vírgula a uma expressão (uma expressão por si só não cria uma tupla, já que os parênteses devem ser usados para agrupamento de expressões). Uma tupla vazia pode ser formada por um par vazio de parênteses.

Bytes

Um objeto de bytes é um vetor imutável. Os itens são bytes de 8 bits, representados por inteiros no intervalo 0 <= x < 256. Literais de bytes (como b'abc') e o construtor embutido bytes() podem ser usado para criar objetos bytes. Além disso, os objetos bytes podem ser decodificados em strings através do método decode().

Sequências Mutáveis

As sequências mutáveis podem ser alteradas após serem criadas. As notações de assinatura e fatiamento podem ser usadas como o destino da atribuição e instruções del (delete, exclusão).

Atualmente, existem dois tipos de sequência mutável intrínseca:

Listas

Os itens de uma lista são objetos Python arbitrários. As listas são formadas colocando uma lista separada por vírgulas de expressões entre colchetes. (Observe que não há casos especiais necessários para formar listas de comprimento 0 ou 1.)

Arrays de Bytes

Um objeto bytearray é um vetor mutável. Eles são criados pelo construtor embutido bytearray(). Além de serem mutáveis (e, portanto, inalteráveis), os vetores de bytes fornecem a mesma interface e funcionalidade que os objetos imutáveis bytes.

O módulo de extensão array fornece um exemplo adicional de um tipo de sequência mutável, assim como o módulo collections.

Tipo Conjunto

Eles representam conjuntos finitos e não ordenados de objetos únicos e imutáveis. Como tal, eles não podem ser indexados por nenhum subscrito. No entanto, eles podem ser iterados, e a função embutida len() retorna o número de itens em um conjunto. Os usos comuns para conjuntos são testes rápidos de associação, remoção de duplicatas de uma sequência e computação de operações matemáticas como interseção, união, diferença e diferença simétrica.

Para elementos de conjunto, as mesmas regras de imutabilidade se aplicam às chaves de dicionário. Observe que os tipos numéricos obedecem às regras normais para comparação numérica: se dois números forem iguais (por exemplo, 1 e 1.0), apenas um deles pode estar contido em um conjunto.

Atualmente, existem dois tipos de conjuntos intrínsecos:

Sets (conjuntos)

Eles representam um conjunto mutável. Eles são criados pelo construtor embutido set() e podem ser modificados posteriormente por vários métodos, como add().

Frozen sets

Eles representam um conjunto imutável. Eles são criados pelo construtor embutido frozenset(). Como um frozenset é imutável e hasheável, ele pode ser usado novamente como um elemento de outro conjunto, ou como uma chave de dicionário.

Mappings

Eles representam conjuntos finitos de objetos indexados por conjuntos de índices arbitrários. A notação subscrito a[k] seleciona o item indexado por k do mapeamento a; isso pode ser usado em expressões e como alvo de atribuições ou instruções del. A função embutida len() retorna o número de itens em um mapeamento.

Atualmente, há um único tipo de mapeamento intrínseco:

Dicionários

Eles representam conjuntos finitos de objetos indexados por valores quase arbitrários. Os únicos tipos de valores não aceitáveis como chaves são os valores que contêm listas ou dicionários ou outros tipos mutáveis que são comparados por valor em vez de por identidade de objeto, o motivo é que a implementação eficiente de dicionários requer que o valor de hash de uma chave permaneça constante. Os tipos numéricos usados para chaves obedecem às regras normais para comparação numérica: se dois números forem iguais (por exemplo, 1 e 1.0), eles podem ser usados alternadamente para indexar a mesma entrada do dicionário.

Os dicionários são mutáveis; eles podem ser criados pela notação {...} (veja a seção Dictionary displays).

Os módulos de extensão dbm.ndbm e dbm.gnu fornecem exemplos adicionais de tipos de mapeamento, assim como o módulo collections.

Tipo Callable

Estes são os tipos aos quais a operação de chamada de função (veja a seção Calls) pode ser aplicada:

Funções Definidas pelo Usuário

Um objeto função definido pelo usuário será criado pela definição de função (veja a seção Definições de função). A mesma deverá ser invocada com uma lista de argumentos contendo o mesmo número de itens que a lista de parâmetros formais da função.

Atributos Especiais:

Atributo

Significado

__doc__

The function’s documentation string, or None if unavailable; not inherited by subclasses

Writable

__name__

O nome da função

Writable

__qualname__

A função qualified name

Novo na versão 3.3.

Writable

__module__

O nome do módulo em que a função foi definida ou None se indisponível.

Writable

__defaults__

A tuple containing default argument values for those arguments that have defaults, or None if no arguments have a default value

Writable

__code__

O objeto código que representa o corpo da função compilada.

Writable

__globals__

Uma referência ao dicionário que contém as variáveis globais da função — o espaço de nomes global do módulo no qual a função foi definida.

Somente Leitura

__dict__

O espaço de nomes que oferece suporte a atributos de função arbitrários.

Writable

__closure__

None or a tuple of cells that contain bindings for the function’s free variables.

Somente Leitura

__annotations__

Um dicionário contendo anotações de parâmetros. As chaves do dict são os nomes dos parâmetros e 'return' para a anotação de retorno, se fornecida.

Writable

__kwdefaults__

Um dicionário contendo padrões para parâmetros somente-nomeados.

Writable

A maioria dos atributos rotulados como “Gravável” verifica o tipo do valor atribuído.

Os objetos de função também suportam a obtenção e configuração de atributos arbitrários, que podem ser usados, por exemplo, para anexar metadados a funções. A notação de ponto de atributo regular é usada para obter e definir esses atributos. Observe que a implementação atual só oferece suporte a atributos de função em funções definidas pelo usuário. Atributos de função embutidas podem ser suportados no futuro.

Additional information about a function’s definition can be retrieved from its code object; see the description of internal types below.

Instância de Métodos

Um objeto de método de instância combina uma classe, uma instância de classe e qualquer objeto chamável (normalmente uma função definida pelo usuário).

Atributos especiais somente leitura: __self__ é o objeto de instância da classe, __func__ é o objeto de função; __doc__ é a documentação do método (mesmo que __func__.__doc__); __ name__ é o nome do método (mesmo que __func__.__name__); __module__ é o nome do módulo no qual o método foi definido, ou None se indisponível.

Os métodos também suportam o acesso (mas não a configuração) dos atributos arbitrários da função no objeto de função subjacente.

Os objetos de método definidos pelo usuário podem ser criados ao se obter um atributo de uma classe (talvez por meio de uma instância dessa classe), se esse atributo for um objeto de função definido pelo usuário ou um objeto de método de classe.

Quando um objeto de método de instância é criado recuperando um objeto de função definido pelo usuário de uma classe por meio de uma de suas instâncias, seu atributo __self__ é a instância, e o objeto de método é considerado vinculado. O atributo __func__ do novo método é o objeto da função original.

When a user-defined method object is created by retrieving another method object from a class or instance, the behaviour is the same as for a function object, except that the __func__ attribute of the new instance is not the original method object but its __func__ attribute.

Quando um objeto de método de instância é criado recuperando um objeto de método de classe de uma classe ou instância, seu atributo __self__ é a própria classe, e seu atributo __func__ é o objeto de função subjacente ao método de classe.

Quando um objeto de método de instância é chamado, a função subjacente (__func__) é chamada, inserindo a instância de classe (__self__) na frente da lista de argumentos. Por exemplo, quando C é uma classe que contém uma definição para uma função f(), e x é uma instância de C, chamando x.f(1) é equivalente a chamar C.f(x, 1).

Quando um objeto de método de instância é derivado de um objeto de método de classe, a “instância de classe” armazenada em __self__ será na verdade a própria classe, de modo que chamar x.f(1) ou C.f(1) é equivalente a chamar f(C,1) sendo f a função subjacente.

Observe que a transformação de objeto de função em objeto de método de instância ocorre sempre que o atributo é recuperado da instância. Em alguns casos, uma otimização frutífera é atribuir o atributo a uma variável local e chamar essa variável local. Observe também que essa transformação ocorre apenas para funções definidas pelo usuário; outros objetos chamáveis (e todos os objetos não chamáveis) são recuperados sem transformação. Também é importante observar que as funções definidas pelo usuário que são atributos de uma instância de classe não são convertidas em métodos vinculados; isso apenas acontece quando a função é um atributo da classe.

Funções Geradoras

A function or method which uses the yield statement (see section A declaração yield) is called a generator function. Such a function, when called, always returns an iterator object which can be used to execute the body of the function: calling the iterator’s iterator.__next__() method will cause the function to execute until it provides a value using the yield statement. When the function executes a return statement or falls off the end, a StopIteration exception is raised and the iterator will have reached the end of the set of values to be returned.

Coroutine functions

Uma função ou um método que é definida(o) usando async def é chamado de função de corrotina. Tal função, quando chamada, retorna um objeto de corrotina. Ele pode conter expressões await, bem como instruções async with e async for. Veja também a seção Objetos Coroutine.

Funções geradoras assíncronas

Uma função ou um método que é definida(o) usando async def e que usa a instrução yield é chamada de função geradora assíncrona. Tal função, quando chamada, retorna um objeto iterador assíncrono que pode ser usado em uma instrução async for para executar o corpo da função.

Chamar o método aiterator.__anext__() do iterador assíncrono retornará um aguardável que, quando aguardado, será executado até fornecer um valor usando a expressão yield. Quando a função executa uma instrução vazia return ou cai no final, uma exceção StopAsyncIteration é levantada e o iterador assíncrono terá alcançado o final do conjunto de valores a serem produzidos.

Funções Built-in

Um objeto função embutida é um wrapper em torno de uma função C. Exemplos de funções embutidas são len() e math.sin() (math é um módulo embutido padrão). O número e o tipo dos argumentos são determinados pela função C. Atributos especiais de somente leitura: __doc__ é a string de documentação da função, ou None se indisponível; __name__ é o nome da função; __self__ é definido como None (mas veja o próximo item); __module__ é o nome do módulo no qual a função foi definida ou None se indisponível.

Métodos Built-in

Este é realmente um disfarce diferente de uma função embutida, desta vez contendo um objeto passado para a função C como um argumento extra implícito. Um exemplo de método embutido é alist.append(), presumindo que alist é um objeto de lista. Nesse caso, o atributo especial de somente leitura __self__ é definido como o objeto denotado por alist.

Classes

Classes são chamáveis. Esses objetos normalmente agem como fábricas para novas instâncias de si mesmos, mas variações são possíveis para tipos de classe que substituem __new__(). Os argumentos da chamada são passados para __new__() e, no caso típico, para __init__() para inicializar a nova instância.

Instância de Classe

Instâncias de classes arbitrárias podem ser tornados chamáveis definindo um método __call__() em sua classe.

Módulos

Modules are a basic organizational unit of Python code, and are created by the import system as invoked either by the import statement (see import), or by calling functions such as importlib.import_module() and built-in __import__(). A module object has a namespace implemented by a dictionary object (this is the dictionary referenced by the __globals__ attribute of functions defined in the module). Attribute references are translated to lookups in this dictionary, e.g., m.x is equivalent to m.__dict__["x"]. A module object does not contain the code object used to initialize the module (since it isn’t needed once the initialization is done).

A atribuição de atributo atualiza o dicionário de espaço de nomes do módulo, por exemplo, m.x = 1 é equivalente a m.__dict__["x"] = 1.

Atributos predefinidos (graváveis): __name__ é o nome do módulo; __doc__ é a string de documentação do módulo, ou None se indisponível; __annotations__ (opcional) é um dicionário contendo anotações de variáveis coletadas durante a execução do corpo do módulo; __file__ é o caminho do arquivo do qual o módulo foi carregado, se ele foi carregado de um arquivo. O atributo __file__ pode estar faltando para certos tipos de módulos, como módulos C que estão estaticamente vinculados ao interpretador; para módulos de extensão carregados dinamicamente de uma biblioteca compartilhada, é o nome do caminho do arquivo da biblioteca compartilhada.

Atributo especial somente leitura: __dict__ é o espaço de nomes do módulo como um objeto de dicionário.

CPython implementation detail: Por causa da maneira como o CPython limpa os dicionários do módulo, o dicionário do módulo será limpo quando o módulo sair do escopo, mesmo se o dicionário ainda tiver referências ativas. Para evitar isso, copie o dicionário ou mantenha o módulo por perto enquanto usa seu dicionário diretamente.

Classes Personalizadas

Tipos de classe personalizados são tipicamente criados por definições de classe (veja a seção Definições de classe). Uma classe possui um espaço de nomes implementado por um objeto de dicionário. As referências de atributos de classe são traduzidas para pesquisas neste dicionário, por exemplo, Cx é traduzido para C.__dict__["x"] (embora haja uma série de ganchos que permitem outros meios de localizar atributos) . Quando o nome do atributo não é encontrado lá, a pesquisa do atributo continua nas classes base. Essa pesquisa das classes base usa a ordem de resolução de métodos C3, que se comporta corretamente mesmo na presença de estruturas de herança “diamante”, onde há vários caminhos de herança que levam de volta a um ancestral comum. Detalhes adicionais sobre o C3 MRO usado pelo Python podem ser encontrados na documentação que acompanha a versão 2.3 em https://www.python.org/download/releases/2.3/mro/.

Quando uma referência de atributo de classe (para uma classe C, digamos) produziria um objeto de método de classe, ele é transformado em um objeto de método de instância cujo atributo __self__ é C. Quando produziria um objeto de método estático, ele é transformado no objeto encapsulado pelo objeto de método estático. Veja a seção Implementing Descriptors para outra maneira em que os atributos recuperados de uma classe podem diferir daqueles realmente contidos em seu __dict__.

As atribuições de atributos de classe atualizam o dicionário da classe, nunca o dicionário de uma classe base.

Um objeto de classe pode ser chamado (veja acima) para produzir uma instância de classe (veja abaixo).

Atributos especiais: __name__ é o nome da classe; __module__ é o nome do módulo no qual a classe foi definida; __dict__ é o dicionário que contém o espaço de nomes da classe; __bases__ é uma tupla contendo as classes base, na ordem de sua ocorrência na lista de classes base; __doc__ é a string de documentação da classe, ou None se indefinido; __annotations__ (opcional) é um dicionário contendo anotações de variáveis coletadas durante a execução do corpo da classe.

Instância de Classe

Uma instância de classe é criada chamando um objeto de classe (veja acima). Uma instância de classe tem um espaço de nomes implementado como um dicionário que é o primeiro lugar no qual as referências de atributos são pesquisadas. Quando um atributo não é encontrado lá, e a classe da instância possui um atributo com esse nome, a pesquisa continua com os atributos da classe. Se for encontrado um atributo de classe que seja um objeto função definido pelo usuário, ele é transformado em um objeto de método de instância cujo atributo __self__ é a instância. Métodos estáticos e objetos de método de classe também são transformados; veja acima em “Classes”. Veja a seção Implementing Descriptors para outra maneira em que os atributos de uma classe recuperados através de suas instâncias podem diferir dos objetos realmente armazenados no __dict__ da classe. Se nenhum atributo de classe for encontrado, e a classe do objeto tiver um método __getattr__(), que é chamado para satisfazer a pesquisa.

As atribuições e exclusões de atributos atualizam o dicionário da instância, nunca o dicionário de uma classe. Se a classe tem um método __setattr__() ou __delattr__(), ele é chamado ao invés de atualizar o dicionário da instância diretamente.

As instâncias de classe podem fingir ser números, sequências ou mapeamentos se tiverem métodos com certos nomes especiais. Veja a seção Nomes de métodos especiais.

Atributos especiais: __dict__ é o dicionário de atributos; __class__ é a classe da instância.

Objetos de E/S (também conhecidos como objetos arquivo)

O objeto de arquivo representa um arquivo aberto. Vários atalhos estão disponíveis para criar objetos arquivos: a função embutida open(), e também os.popen(), os.fdopen() e o método makefile() de objetos soquete (e talvez por outras funções ou métodos fornecidos por módulos de extensão).

Os objetos sys.stdin, sys.stdout e sys.stderr são inicializados para objetos arquivo que correspondem aos fluxos de entrada, saída e erro padrão do interpretador; eles são todos abertos em modo texto e, portanto, seguem a interface definida pela classe abstrata io.TextIOBase.

Tipos Internos

Alguns tipos usados internamente pelo interpretador são expostos ao usuário. Suas definições podem mudar com versões futuras do interpretador, mas são mencionadas aqui para fins de integridade.

Objeto Código

Objetos código representam código Python executável compilados em bytes ou bytecode. A diferença entre um objeto código e um objeto função é que o objeto função contém uma referência explícita aos globais da função (o módulo no qual foi definida), enquanto um objeto código não contém nenhum contexto; também os valores de argumento padrão são armazenados no objeto função, não no objeto código (porque eles representam os valores calculados em tempo de execução). Ao contrário dos objetos função, os objetos código são imutáveis e não contêm referências (direta ou indiretamente) a objetos mutáveis.

Special read-only attributes: co_name gives the function name; co_argcount is the number of positional arguments (including arguments with default values); co_nlocals is the number of local variables used by the function (including arguments); co_varnames is a tuple containing the names of the local variables (starting with the argument names); co_cellvars is a tuple containing the names of local variables that are referenced by nested functions; co_freevars is a tuple containing the names of free variables; co_code is a string representing the sequence of bytecode instructions; co_consts is a tuple containing the literals used by the bytecode; co_names is a tuple containing the names used by the bytecode; co_filename is the filename from which the code was compiled; co_firstlineno is the first line number of the function; co_lnotab is a string encoding the mapping from bytecode offsets to line numbers (for details see the source code of the interpreter); co_stacksize is the required stack size (including local variables); co_flags is an integer encoding a number of flags for the interpreter.

Os seguintes bits de sinalizador são definidos para co_flags: o bit 0x04 é definido se a função usa a sintaxe *arguments para aceitar um número arbitrário de argumentos posicionais; o bit 0x08 é definido se a função usa a sintaxe **keywords para aceitar argumentos nomeados arbitrários; o bit 0x20 é definido se a função for um gerador.

Declarações de recursos futuros (from __future__ import division) também usam bits em co_flags para indicar se um objeto código foi compilado com um recurso específico habilitado: o bit 0x2000 é definido se a função foi compilada com divisão futura habilitada; os bits 0x10 e 0x1000 foram usados em versões anteriores do Python.

Outros bits em co_flags são reservados para uso interno.

Se um objeto código representa uma função, o primeiro item em co_consts é a string de documentação da função, ou None se indefinido.

Objetos quadro

Frame objects represent execution frames. They may occur in traceback objects (see below).

Atributos especiais de somente leitura: f_back é para o quadro de pilha anterior (para o chamador), ou None se este é o quadro de pilha inferior; f_code é o objeto código sendo executado neste quadro; f_locals é o dicionário usado para procurar variáveis locais; f_globals é usado para variáveis globais; f_builtins é usado para nomes embutidos (intrínsecos); f_lasti dá a instrução precisa (este é um índice para a string bytecode do objeto código).

Special writable attributes: f_trace, if not None, is a function called at the start of each source code line (this is used by the debugger); f_lineno is the current line number of the frame — writing to this from within a trace function jumps to the given line (only for the bottom-most frame). A debugger can implement a Jump command (aka Set Next Statement) by writing to f_lineno.

Objetos quadro têm suporte a um método:

frame.clear()

Este método limpa todas as referências a variáveis locais mantidas pelo quadro. Além disso, se o quadro pertencer a um gerador, o gerador é finalizado. Isso ajuda a quebrar os ciclos de referência que envolvem objetos quadro (por exemplo, ao capturar uma exceção e armazenar seu traceback para uso posterior).

RuntimeError é levantada se o quadro estiver em execução.

Novo na versão 3.4.

Objetos traceback

Traceback objects represent a stack trace of an exception. A traceback object is created when an exception occurs. When the search for an exception handler unwinds the execution stack, at each unwound level a traceback object is inserted in front of the current traceback. When an exception handler is entered, the stack trace is made available to the program. (See section The try statement.) It is accessible as the third item of the tuple returned by sys.exc_info(). When the program contains no suitable handler, the stack trace is written (nicely formatted) to the standard error stream; if the interpreter is interactive, it is also made available to the user as sys.last_traceback.

Special read-only attributes: tb_next is the next level in the stack trace (towards the frame where the exception occurred), or None if there is no next level; tb_frame points to the execution frame of the current level; tb_lineno gives the line number where the exception occurred; tb_lasti indicates the precise instruction. The line number and last instruction in the traceback may differ from the line number of its frame object if the exception occurred in a try statement with no matching except clause or with a finally clause.

Objetos slice

Objetos slice são usados para representar fatias para métodos __getitem__(). Eles também são criados pela função embutida slice().

Atributos especiais de somente leitura: start é o limite inferior; stop é o limite superior; step é o valor intermediário; cada um é None se omitido. Esses atributos podem ter qualquer tipo.

Objetos slice têm suporte a um método:

slice.indices(self, length)

Este método usa um único argumento inteiro length e calcula informações sobre a fatia que o objeto slice descreveria se aplicado a uma sequência de itens de length. Ele retorna uma tupla de três inteiros; respectivamente, estes são os índices start e stop e o step ou comprimento de avanços da fatia. Índices ausentes ou fora dos limites são tratados de maneira consistente com fatias regulares.

Objetos método estáticos

Objetos método estáticos fornecem uma maneira de derrotar a transformação de objetos função em objetos método descritos acima. Um objeto método estático é um wrapper em torno de qualquer outro objeto, geralmente um objeto método definido pelo usuário. Quando um objeto método estático é recuperado de uma classe ou instância de classe, o objeto realmente retornado é o objeto envolto, que não está sujeito a nenhuma transformação posterior. Os objetos método estáticos não são chamáveis, embora os objetos que envolvem geralmente o sejam. Objetos método estáticos são criados pelo construtor embutido staticmethod().

Objetos métodos de classe

Um objeto método de classe, como um objeto método estático, é um invólucro em torno de outro objeto que altera a maneira como esse objeto é recuperado de classes e instâncias de classe. O comportamento dos objetos de método de classe após tal recuperação é descrito acima, em “Métodos definidos pelo usuário”. Objetos de método de classe são criados pelo construtor embutido classmethod().

3.3. Nomes de métodos especiais

Uma classe pode implementar certas operações que são chamadas por sintaxe especial (como operações aritméticas ou subscript e fatiamento), definindo métodos com nomes especiais. Esta é a abordagem do Python para sobrecarga de operador, permitindo que as classes definam seu próprio comportamento em relação aos operadores da linguagem. Por exemplo, se uma classe define um método chamado __getitem__(), e x é uma instância desta classe, então x[i] é aproximadamente equivalente a type(x).__getitem__(x, i). Exceto onde mencionado, as tentativas de executar uma operação levantam uma exceção quando nenhum método apropriado é definido (tipicamente AttributeError ou TypeError).

Definir um método especial para None indica que a operação correspondente não está disponível. Por exemplo, se uma classe define __iter__() para None, a classe não é iterável, então chamar iter() em suas instâncias irá levantar um TypeError (sem retroceder para __getitem__()). 2

Ao implementar uma classe que emula qualquer tipo embutido, é importante que a emulação seja implementada apenas na medida em que faça sentido para o objeto que está sendo modelado. Por exemplo, algumas sequências podem funcionar bem com a recuperação de elementos individuais, mas extrair uma fatia pode não fazer sentido. (Um exemplo disso é a interface NodeList no Document Object Model do W3C.)

3.3.1. Customização básica

object.__new__(cls[, ...])

Chamado para criar uma nova instância da classe cls. __new__() é um método estático (é um caso especial, então você não precisa declará-lo como tal) que recebe a classe da qual uma instância foi solicitada como seu primeiro argumento. Os argumentos restantes são aqueles passados para a expressão do construtor do objeto (a chamada para a classe). O valor de retorno de __new__() deve ser a nova instância do objeto (geralmente uma instância de cls).

Implementações típicas criam uma nova instância da classe invocando o método __new__() da superclasse usando super().__new__(cls[, ...]) com os argumentos apropriados e, em seguida, modificando a instância recém-criada conforme necessário antes de retorná-la.

If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().

Se __new__() não retornar uma instância de cls, então o método __init__() da nova instância não será invocado.

__new__() destina-se principalmente a permitir que subclasses de tipos imutáveis (como int, str ou tupla) personalizem a criação de instâncias. Também é comumente substituído em metaclasses personalizadas para personalizar a criação de classes.

object.__init__(self[, ...])

Chamado após a instância ter sido criada (por __new__()), mas antes de ser retornada ao chamador. Os argumentos são aqueles passados para a expressão do construtor da classe. Se uma classe base tem um método __init__(), o método __init__() da classe derivada, se houver, deve chamá-lo explicitamente para garantir a inicialização apropriada da parte da classe base da instância; por exemplo: super().__init__([args...]).

Porque __new__() e :meth: __init__` trabalham juntos na construção de objetos (__new__() para criá-lo e __init__() para personalizá-lo), nenhum valor diferente de None pode ser retornado por __init__(); fazer isso fará com que uma TypeError seja levantada em tempo de execução.

object.__del__(self)

Chamado quando a instância está prestes a ser destruída. Também é chamada de finalizador ou (incorretamente) de destruidor. Se uma classe base tem um método __del__(), o método __del__() da classe derivada, se houver, deve chamá-lo explicitamente para garantir a exclusão adequada da parte da classe base da instância.

É possível (embora não recomendado!) para o método __del__() adiar a destruição da instância criando uma nova referência a ela. Isso é chamado de ressurreição de objeto. Depende da implementação se __del__() é chamado uma segunda vez quando um objeto ressuscitado está prestes a ser destruído; a implementação atual do CPython apenas o chama uma vez.

Não é garantido que os métodos __del__() sejam chamados para objetos que ainda existam quando o interpretador sai.

Nota

del x não chama diretamente x.__del__() – o primeiro diminui a contagem de referências para x em um, e o segundo só é chamado quando a contagem de referências de x atinge zero.

CPython implementation detail: It is possible for a reference cycle to prevent the reference count of an object from going to zero. In this case, the cycle will be later detected and deleted by the cyclic garbage collector. A common cause of reference cycles is when an exception has been caught in a local variable. The frame’s locals then reference the exception, which references its own traceback, which references the locals of all frames caught in the traceback.

Ver também

Documentação do módulo gc.

Aviso

Devido às circunstâncias precárias sob as quais os métodos __del__() são invocados, as exceções que ocorrem durante sua execução são ignoradas e um aviso é impresso em sys.stderr em seu lugar. Em particular:

  • __del__() pode ser chamado quando um código arbitrário está sendo executado, incluindo de qualquer thread arbitrário. Se __del__() precisar bloquear ou invocar qualquer outro recurso de bloqueio, pode ocorrer um deadlock, pois o recurso já pode ter sido levado pelo código que é interrompido para executar __del__().

  • __del__() pode ser executado durante o desligamento do interpretador. Como consequência, as variáveis globais que ele precisa acessar (incluindo outros módulos) podem já ter sido excluídas ou definidas como None. O Python garante que os globais cujo nome comece com um único sublinhado sejam excluídos de seu módulo antes que outros globais sejam excluídos; se nenhuma outra referência a tais globais existir, isso pode ajudar a garantir que os módulos importados ainda estejam disponíveis no momento em que o método __del__() for chamado.

object.__repr__(self)

Chamado pela função embutida repr() para calcular a representação da string “oficial” de um objeto. Se possível, isso deve parecer uma expressão Python válida que pode ser usada para recriar um objeto com o mesmo valor (dado um ambiente apropriado). Se isso não for possível, uma string no formato <...alguma descrição útil...> deve ser retornada. O valor de retorno deve ser um objeto string. Se uma classe define __repr__(), mas não __str__(), então __repr__() também é usado quando uma representação de string “informal” de instâncias daquela classe é necessária.

Isso é normalmente usado para depuração, portanto, é importante que a representação seja rica em informações e inequívoca.

object.__str__(self)

Chamado por str(object) e as funções embutidas format() e print() para calcular a representação da string “informal” ou agradável para exibição de um objeto. O valor de retorno deve ser um objeto string.

Este método difere de object.__repr__() por não haver expectativa de que __str__() retorne uma expressão Python válida: uma representação mais conveniente ou concisa pode ser usada.

A implementação padrão definida pelo tipo embutido object chama object.__repr__().

object.__bytes__(self)

Chamado por bytes para calcular uma representação de string de bytes de um objeto. Isso deve retornar um objeto bytes.

object.__format__(self, format_spec)

Called by the format() built-in function, and by extension, evaluation of formatted string literals and the str.format() method, to produce a “formatted” string representation of an object. The format_spec argument is a string that contains a description of the formatting options desired. The interpretation of the format_spec argument is up to the type implementing __format__(), however most classes will either delegate formatting to one of the built-in types, or use a similar formatting option syntax.

Consulte Format Specification Mini-Language para uma descrição da sintaxe de formatação padrão.

O valor de retorno deve ser um objeto string.

Alterado na versão 3.4: O método __format__ do próprio object levanta uma TypeError se passada qualquer string não vazia.

object.__lt__(self, other)
object.__le__(self, other)
object.__eq__(self, other)
object.__ne__(self, other)
object.__gt__(self, other)
object.__ge__(self, other)

Esses são os chamados métodos de “comparação rica”. A correspondência entre os símbolos do operador e os nomes dos métodos é a seguinte: x<y chama x.__lt__(y), x<=y chama x.__le__(y), x==y chama x.__eq__(y), x!=y chama x.__ne__(y), x>y chama x.__gt__(y) e x>=y chama x.__ge__(y).

Um método de comparação rico pode retornar o singleton NotImplemented se não implementar a operação para um determinado par de argumentos. Por convenção, False e True são retornados para uma comparação bem-sucedida. No entanto, esses métodos podem retornar qualquer valor, portanto, se o operador de comparação for usado em um contexto booleano (por exemplo, na condição de uma instrução if), Python irá chamar bool() no valor para determinar se o resultado for verdadeiro ou falso.

Por padrão, __ne__() delega para __eq__() e inverte o resultado a menos que seja NotImplemented. Não há outras relações implícitas entre os operadores de comparação, por exemplo, a verdade de (x<y or x==y) não implica x<=y. Para gerar operações de ordenação automaticamente a partir de uma única operação raiz, consulte functools.total_ordering().

Veja o parágrafo sobre __hash__() para algumas notas importantes sobre a criação de objetos hasheáveis que suportam operações de comparação personalizadas e são utilizáveis como chaves de dicionário.

Não há versões de argumentos trocados desses métodos (a serem usados quando o argumento esquerdo não tem suporta à operação, mas o argumento direito sim); em vez disso, __lt__() e __gt__() são o reflexo um do outro, __le__() e __ge__() são o reflexo um do outro, e __eq__() e __ne__() são seu próprio reflexo. Se os operandos são de tipos diferentes e o tipo do operando direito é uma subclasse direta ou indireta do tipo do operando esquerdo, o método refletido do operando direito tem prioridade, caso contrário, o método do operando esquerdo tem prioridade. A subclasse virtual não é considerada.

object.__hash__(self)

Chamado pela função embutida hash() e para operações em membros de coleções em hash incluindo set, frozenset e dict. __hash__() deve retornar um inteiro. A única propriedade necessária é que os objetos que são comparados iguais tenham o mesmo valor de hash; é aconselhável misturar os valores hash dos componentes do objeto que também desempenham um papel na comparação dos objetos, empacotando-os em uma tupla e fazendo o hash da tupla. Exemplo:

def __hash__(self):
    return hash((self.name, self.nick, self.color))

Nota

hash() trunca o valor retornado do método __hash__() personalizado de um objeto para o tamanho de um Py_ssize_t. Isso é normalmente 8 bytes em compilações de 64 bits e 4 bytes em compilações de 32 bits. Se o __hash__() de um objeto deve interoperar em compilações de tamanhos de bits diferentes, certifique-se de verificar a largura em todas as compilações suportadas. Uma maneira fácil de fazer isso é com python -c "import sys; print(sys.hash_info.width)".

Se uma classe não define um método __eq__(), ela também não deve definir uma operação __hash__(); se define __eq__() mas não __hash__(), suas instâncias não serão utilizáveis como itens em coleções hasheáveis. Se uma classe define objetos mutáveis e implementa um método __eq__(), ela não deve implementar __hash__(), uma vez que a implementação de coleções hasheáveis requer que o valor hash de uma chave seja imutável (se o valor hash do objeto mudar, estará no balde de hash errado).

As classes definidas pelo usuário têm os métodos __eq__() e __hash__() por padrão; com eles, todos os objetos se comparam desiguais (exceto com eles mesmos) e x.__hash__() retorna um valor apropriado tal que x == y implica que x is y e hash(x) == hash(y).

A class that overrides __eq__() and does not define __hash__() will have its __hash__() implicitly set to None. When the __hash__() method of a class is None, instances of the class will raise an appropriate TypeError when a program attempts to retrieve their hash value, and will also be correctly identified as unhashable when checking isinstance(obj, collections.Hashable).

Se uma classe que sobrescreve __eq__() precisa manter a implementação de __hash__() de uma classe pai, o interpretador deve ser informado disso explicitamente pela configuração __hash__ = <ClassePai>.__hash__.

If a class that does not override __eq__() wishes to suppress hash support, it should include __hash__ = None in the class definition. A class which defines its own __hash__() that explicitly raises a TypeError would be incorrectly identified as hashable by an isinstance(obj, collections.Hashable) call.

Nota

By default, the __hash__() values of str, bytes and datetime objects are “salted” with an unpredictable random value. Although they remain constant within an individual Python process, they are not predictable between repeated invocations of Python.

Isso se destina a fornecer proteção contra uma negação de serviço causada por entradas cuidadosamente escolhidas que exploram o pior caso de desempenho de uma inserção de dicionário, complexidade O(n^2). Consulte http://www.ocert.org/advisories/ocert-2011-003.html para obter detalhes.

Changing hash values affects the iteration order of dicts, sets and other mappings. Python has never made guarantees about this ordering (and it typically varies between 32-bit and 64-bit builds).

Consulte também PYTHONHASHSEED.

Alterado na versão 3.3: Aleatorização de hash está habilitada por padrão.

object.__bool__(self)

Called to implement truth value testing and the built-in operation bool(); should return False or True. When this method is not defined, __len__() is called, if it is defined, and the object is considered true if its result is nonzero. If a class defines neither __len__() nor __bool__(), all its instances are considered true.

3.3.2. Customizing attribute access

The following methods can be defined to customize the meaning of attribute access (use of, assignment to, or deletion of x.name) for class instances.

object.__getattr__(self, name)

Called when the default attribute access fails with an AttributeError (either __getattribute__() raises an AttributeError because name is not an instance attribute or an attribute in the class tree for self; or __get__() of a name property raises AttributeError). This method should either return the (computed) attribute value or raise an AttributeError exception.

Note that if the attribute is found through the normal mechanism, __getattr__() is not called. (This is an intentional asymmetry between __getattr__() and __setattr__().) This is done both for efficiency reasons and because otherwise __getattr__() would have no way to access other attributes of the instance. Note that at least for instance variables, you can fake total control by not inserting any values in the instance attribute dictionary (but instead inserting them in another object). See the __getattribute__() method below for a way to actually get total control over attribute access.

object.__getattribute__(self, name)

Called unconditionally to implement attribute accesses for instances of the class. If the class also defines __getattr__(), the latter will not be called unless __getattribute__() either calls it explicitly or raises an AttributeError. This method should return the (computed) attribute value or raise an AttributeError exception. In order to avoid infinite recursion in this method, its implementation should always call the base class method with the same name to access any attributes it needs, for example, object.__getattribute__(self, name).

Nota

This method may still be bypassed when looking up special methods as the result of implicit invocation via language syntax or built-in functions. See Special method lookup.

object.__setattr__(self, name, value)

Called when an attribute assignment is attempted. This is called instead of the normal mechanism (i.e. store the value in the instance dictionary). name is the attribute name, value is the value to be assigned to it.

If __setattr__() wants to assign to an instance attribute, it should call the base class method with the same name, for example, object.__setattr__(self, name, value).

object.__delattr__(self, name)

Like __setattr__() but for attribute deletion instead of assignment. This should only be implemented if del obj.name is meaningful for the object.

object.__dir__(self)

Called when dir() is called on the object. A sequence must be returned. dir() converts the returned sequence to a list and sorts it.

3.3.2.1. Customizing module attribute access

For a more fine grained customization of the module behavior (setting attributes, properties, etc.), one can set the __class__ attribute of a module object to a subclass of types.ModuleType. For example:

import sys
from types import ModuleType

class VerboseModule(ModuleType):
    def __repr__(self):
        return f'Verbose {self.__name__}'

    def __setattr__(self, attr, value):
        print(f'Setting {attr}...')
        setattr(self, attr, value)

sys.modules[__name__].__class__ = VerboseModule

Nota

Setting module __class__ only affects lookups made using the attribute access syntax – directly accessing the module globals (whether by code within the module, or via a reference to the module’s globals dictionary) is unaffected.

Alterado na versão 3.5: __class__ module attribute is now writable.

3.3.2.2. Implementing Descriptors

The following methods only apply when an instance of the class containing the method (a so-called descriptor class) appears in an owner class (the descriptor must be in either the owner’s class dictionary or in the class dictionary for one of its parents). In the examples below, “the attribute” refers to the attribute whose name is the key of the property in the owner class’ __dict__.

object.__get__(self, instance, owner)

Called to get the attribute of the owner class (class attribute access) or of an instance of that class (instance attribute access). owner is always the owner class, while instance is the instance that the attribute was accessed through, or None when the attribute is accessed through the owner. This method should return the (computed) attribute value or raise an AttributeError exception.

object.__set__(self, instance, value)

Called to set the attribute on an instance instance of the owner class to a new value, value.

object.__delete__(self, instance)

Called to delete the attribute on an instance instance of the owner class.

object.__set_name__(self, owner, name)

Called at the time the owning class owner is created. The descriptor has been assigned to name.

Novo na versão 3.6.

The attribute __objclass__ is interpreted by the inspect module as specifying the class where this object was defined (setting this appropriately can assist in runtime introspection of dynamic class attributes). For callables, it may indicate that an instance of the given type (or a subclass) is expected or required as the first positional argument (for example, CPython sets this attribute for unbound methods that are implemented in C).

3.3.2.3. Invoking Descriptors

In general, a descriptor is an object attribute with “binding behavior”, one whose attribute access has been overridden by methods in the descriptor protocol: __get__(), __set__(), and __delete__(). If any of those methods are defined for an object, it is said to be a descriptor.

The default behavior for attribute access is to get, set, or delete the attribute from an object’s dictionary. For instance, a.x has a lookup chain starting with a.__dict__['x'], then type(a).__dict__['x'], and continuing through the base classes of type(a) excluding metaclasses.

However, if the looked-up value is an object defining one of the descriptor methods, then Python may override the default behavior and invoke the descriptor method instead. Where this occurs in the precedence chain depends on which descriptor methods were defined and how they were called.

The starting point for descriptor invocation is a binding, a.x. How the arguments are assembled depends on a:

Direct Call

The simplest and least common call is when user code directly invokes a descriptor method: x.__get__(a).

Instance Binding

If binding to an object instance, a.x is transformed into the call: type(a).__dict__['x'].__get__(a, type(a)).

Class Binding

If binding to a class, A.x is transformed into the call: A.__dict__['x'].__get__(None, A).

Super Binding

If a is an instance of super, then the binding super(B, obj).m() searches obj.__class__.__mro__ for the base class A immediately preceding B and then invokes the descriptor with the call: A.__dict__['m'].__get__(obj, obj.__class__).

For instance bindings, the precedence of descriptor invocation depends on the which descriptor methods are defined. A descriptor can define any combination of __get__(), __set__() and __delete__(). If it does not define __get__(), then accessing the attribute will return the descriptor object itself unless there is a value in the object’s instance dictionary. If the descriptor defines __set__() and/or __delete__(), it is a data descriptor; if it defines neither, it is a non-data descriptor. Normally, data descriptors define both __get__() and __set__(), while non-data descriptors have just the __get__() method. Data descriptors with __set__() and __get__() defined always override a redefinition in an instance dictionary. In contrast, non-data descriptors can be overridden by instances.

Python methods (including staticmethod() and classmethod()) are implemented as non-data descriptors. Accordingly, instances can redefine and override methods. This allows individual instances to acquire behaviors that differ from other instances of the same class.

The property() function is implemented as a data descriptor. Accordingly, instances cannot override the behavior of a property.

3.3.2.4. __slots__

__slots__ allow us to explicitly declare data members (like properties) and deny the creation of __dict__ and __weakref__ (unless explicitly declared in __slots__ or available in a parent.)

The space saved over using __dict__ can be significant.

object.__slots__

This class variable can be assigned a string, iterable, or sequence of strings with variable names used by instances. __slots__ reserves space for the declared variables and prevents the automatic creation of __dict__ and __weakref__ for each instance.

3.3.2.4.1. Notes on using __slots__
  • When inheriting from a class without __slots__, the __dict__ and __weakref__ attribute of the instances will always be accessible.

  • Without a __dict__ variable, instances cannot be assigned new variables not listed in the __slots__ definition. Attempts to assign to an unlisted variable name raises AttributeError. If dynamic assignment of new variables is desired, then add '__dict__' to the sequence of strings in the __slots__ declaration.

  • Without a __weakref__ variable for each instance, classes defining __slots__ do not support weak references to its instances. If weak reference support is needed, then add '__weakref__' to the sequence of strings in the __slots__ declaration.

  • __slots__ are implemented at the class level by creating descriptors (Implementing Descriptors) for each variable name. As a result, class attributes cannot be used to set default values for instance variables defined by __slots__; otherwise, the class attribute would overwrite the descriptor assignment.

  • The action of a __slots__ declaration is not limited to the class where it is defined. __slots__ declared in parents are available in child classes. However, child subclasses will get a __dict__ and __weakref__ unless they also define __slots__ (which should only contain names of any additional slots).

  • If a class defines a slot also defined in a base class, the instance variable defined by the base class slot is inaccessible (except by retrieving its descriptor directly from the base class). This renders the meaning of the program undefined. In the future, a check may be added to prevent this.

  • Nonempty __slots__ does not work for classes derived from “variable-length” built-in types such as int, bytes and tuple.

  • Any non-string iterable may be assigned to __slots__. Mappings may also be used; however, in the future, special meaning may be assigned to the values corresponding to each key.

  • __class__ assignment works only if both classes have the same __slots__.

  • Multiple inheritance with multiple slotted parent classes can be used, but only one parent is allowed to have attributes created by slots (the other bases must have empty slot layouts) - violations raise TypeError.

3.3.3. Customizing class creation

Whenever a class inherits from another class, __init_subclass__ is called on that class. This way, it is possible to write classes which change the behavior of subclasses. This is closely related to class decorators, but where class decorators only affect the specific class they’re applied to, __init_subclass__ solely applies to future subclasses of the class defining the method.

classmethod object.__init_subclass__(cls)

This method is called whenever the containing class is subclassed. cls is then the new subclass. If defined as a normal instance method, this method is implicitly converted to a class method.

Keyword arguments which are given to a new class are passed to the parent’s class __init_subclass__. For compatibility with other classes using __init_subclass__, one should take out the needed keyword arguments and pass the others over to the base class, as in:

class Philosopher:
    def __init_subclass__(cls, default_name, **kwargs):
        super().__init_subclass__(**kwargs)
        cls.default_name = default_name

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    pass

The default implementation object.__init_subclass__ does nothing, but raises an error if it is called with any arguments.

Nota

The metaclass hint metaclass is consumed by the rest of the type machinery, and is never passed to __init_subclass__ implementations. The actual metaclass (rather than the explicit hint) can be accessed as type(cls).

Novo na versão 3.6.

3.3.3.1. Metaclasses

By default, classes are constructed using type(). The class body is executed in a new namespace and the class name is bound locally to the result of type(name, bases, namespace).

The class creation process can be customized by passing the metaclass keyword argument in the class definition line, or by inheriting from an existing class that included such an argument. In the following example, both MyClass and MySubclass are instances of Meta:

class Meta(type):
    pass

class MyClass(metaclass=Meta):
    pass

class MySubclass(MyClass):
    pass

Any other keyword arguments that are specified in the class definition are passed through to all metaclass operations described below.

When a class definition is executed, the following steps occur:

  • the appropriate metaclass is determined

  • the class namespace is prepared

  • the class body is executed

  • the class object is created

3.3.3.2. Determining the appropriate metaclass

The appropriate metaclass for a class definition is determined as follows:

  • if no bases and no explicit metaclass are given, then type() is used

  • if an explicit metaclass is given and it is not an instance of type(), then it is used directly as the metaclass

  • if an instance of type() is given as the explicit metaclass, or bases are defined, then the most derived metaclass is used

The most derived metaclass is selected from the explicitly specified metaclass (if any) and the metaclasses (i.e. type(cls)) of all specified base classes. The most derived metaclass is one which is a subtype of all of these candidate metaclasses. If none of the candidate metaclasses meets that criterion, then the class definition will fail with TypeError.

3.3.3.3. Preparing the class namespace

Once the appropriate metaclass has been identified, then the class namespace is prepared. If the metaclass has a __prepare__ attribute, it is called as namespace = metaclass.__prepare__(name, bases, **kwds) (where the additional keyword arguments, if any, come from the class definition).

If the metaclass has no __prepare__ attribute, then the class namespace is initialised as an empty ordered mapping.

Ver também

PEP 3115 - Metaclasses no Python 3000

Introduzido o gancho de espaço de nomes __prepare__

3.3.3.4. Executing the class body

The class body is executed (approximately) as exec(body, globals(), namespace). The key difference from a normal call to exec() is that lexical scoping allows the class body (including any methods) to reference names from the current and outer scopes when the class definition occurs inside a function.

However, even when the class definition occurs inside the function, methods defined inside the class still cannot see names defined at the class scope. Class variables must be accessed through the first parameter of instance or class methods, or through the implicit lexically scoped __class__ reference described in the next section.

3.3.3.5. Creating the class object

Once the class namespace has been populated by executing the class body, the class object is created by calling metaclass(name, bases, namespace, **kwds) (the additional keywords passed here are the same as those passed to __prepare__).

This class object is the one that will be referenced by the zero-argument form of super(). __class__ is an implicit closure reference created by the compiler if any methods in a class body refer to either __class__ or super. This allows the zero argument form of super() to correctly identify the class being defined based on lexical scoping, while the class or instance that was used to make the current call is identified based on the first argument passed to the method.

CPython implementation detail: In CPython 3.6 and later, the __class__ cell is passed to the metaclass as a __classcell__ entry in the class namespace. If present, this must be propagated up to the type.__new__ call in order for the class to be initialised correctly. Failing to do so will result in a DeprecationWarning in Python 3.6, and a RuntimeError in Python 3.8.

When using the default metaclass type, or any metaclass that ultimately calls type.__new__, the following additional customisation steps are invoked after creating the class object:

  • first, type.__new__ collects all of the descriptors in the class namespace that define a __set_name__() method;

  • second, all of these __set_name__ methods are called with the class being defined and the assigned name of that particular descriptor; and

  • finally, the __init_subclass__() hook is called on the immediate parent of the new class in its method resolution order.

After the class object is created, it is passed to the class decorators included in the class definition (if any) and the resulting object is bound in the local namespace as the defined class.

When a new class is created by type.__new__, the object provided as the namespace parameter is copied to a new ordered mapping and the original object is discarded. The new copy is wrapped in a read-only proxy, which becomes the __dict__ attribute of the class object.

Ver também

PEP 3135 - New super

Describes the implicit __class__ closure reference

3.3.3.6. Uses for metaclasses

The potential uses for metaclasses are boundless. Some ideas that have been explored include enum, logging, interface checking, automatic delegation, automatic property creation, proxies, frameworks, and automatic resource locking/synchronization.

3.3.4. Customizing instance and subclass checks

The following methods are used to override the default behavior of the isinstance() and issubclass() built-in functions.

In particular, the metaclass abc.ABCMeta implements these methods in order to allow the addition of Abstract Base Classes (ABCs) as “virtual base classes” to any class or type (including built-in types), including other ABCs.

class.__instancecheck__(self, instance)

Return true if instance should be considered a (direct or indirect) instance of class. If defined, called to implement isinstance(instance, class).

class.__subclasscheck__(self, subclass)

Return true if subclass should be considered a (direct or indirect) subclass of class. If defined, called to implement issubclass(subclass, class).

Note that these methods are looked up on the type (metaclass) of a class. They cannot be defined as class methods in the actual class. This is consistent with the lookup of special methods that are called on instances, only in this case the instance is itself a class.

Ver também

PEP 3119 - Introducing Abstract Base Classes

Includes the specification for customizing isinstance() and issubclass() behavior through __instancecheck__() and __subclasscheck__(), with motivation for this functionality in the context of adding Abstract Base Classes (see the abc module) to the language.

3.3.5. Emulating callable objects

object.__call__(self[, args...])

Called when the instance is “called” as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...).

3.3.6. Emulating container types

The following methods can be defined to implement container objects. Containers usually are sequences (such as lists or tuples) or mappings (like dictionaries), but can represent other containers as well. The first set of methods is used either to emulate a sequence or to emulate a mapping; the difference is that for a sequence, the allowable keys should be the integers k for which 0 <= k < N where N is the length of the sequence, or slice objects, which define a range of items. It is also recommended that mappings provide the methods keys(), values(), items(), get(), clear(), setdefault(), pop(), popitem(), copy(), and update() behaving similar to those for Python’s standard dictionary objects. The collections module provides a MutableMapping abstract base class to help create those methods from a base set of __getitem__(), __setitem__(), __delitem__(), and keys(). Mutable sequences should provide methods append(), count(), index(), extend(), insert(), pop(), remove(), reverse() and sort(), like Python standard list objects. Finally, sequence types should implement addition (meaning concatenation) and multiplication (meaning repetition) by defining the methods __add__(), __radd__(), __iadd__(), __mul__(), __rmul__() and __imul__() described below; they should not define other numerical operators. It is recommended that both mappings and sequences implement the __contains__() method to allow efficient use of the in operator; for mappings, in should search the mapping’s keys; for sequences, it should search through the values. It is further recommended that both mappings and sequences implement the __iter__() method to allow efficient iteration through the container; for mappings, __iter__() should be the same as keys(); for sequences, it should iterate through the values.

object.__len__(self)

Called to implement the built-in function len(). Should return the length of the object, an integer >= 0. Also, an object that doesn’t define a __bool__() method and whose __len__() method returns zero is considered to be false in a Boolean context.

CPython implementation detail: In CPython, the length is required to be at most sys.maxsize. If the length is larger than sys.maxsize some features (such as len()) may raise OverflowError. To prevent raising OverflowError by truth value testing, an object must define a __bool__() method.

object.__length_hint__(self)

Called to implement operator.length_hint(). Should return an estimated length for the object (which may be greater or less than the actual length). The length must be an integer >= 0. This method is purely an optimization and is never required for correctness.

Novo na versão 3.4.

Nota

Slicing is done exclusively with the following three methods. A call like

a[1:2] = b

is translated to

a[slice(1, 2, None)] = b

and so forth. Missing slice items are always filled in with None.

object.__getitem__(self, key)

Called to implement evaluation of self[key]. For sequence types, the accepted keys should be integers and slice objects. Note that the special interpretation of negative indexes (if the class wishes to emulate a sequence type) is up to the __getitem__() method. If key is of an inappropriate type, TypeError may be raised; if of a value outside the set of indexes for the sequence (after any special interpretation of negative values), IndexError should be raised. For mapping types, if key is missing (not in the container), KeyError should be raised.

Nota

for loops expect that an IndexError will be raised for illegal indexes to allow proper detection of the end of the sequence.

object.__setitem__(self, key, value)

Called to implement assignment to self[key]. Same note as for __getitem__(). This should only be implemented for mappings if the objects support changes to the values for keys, or if new keys can be added, or for sequences if elements can be replaced. The same exceptions should be raised for improper key values as for the __getitem__() method.

object.__delitem__(self, key)

Called to implement deletion of self[key]. Same note as for __getitem__(). This should only be implemented for mappings if the objects support removal of keys, or for sequences if elements can be removed from the sequence. The same exceptions should be raised for improper key values as for the __getitem__() method.

object.__missing__(self, key)

Called by dict.__getitem__() to implement self[key] for dict subclasses when key is not in the dictionary.

object.__iter__(self)

This method is called when an iterator is required for a container. This method should return a new iterator object that can iterate over all the objects in the container. For mappings, it should iterate over the keys of the container.

Iterator objects also need to implement this method; they are required to return themselves. For more information on iterator objects, see Tipos de Iteradores.

object.__reversed__(self)

Called (if present) by the reversed() built-in to implement reverse iteration. It should return a new iterator object that iterates over all the objects in the container in reverse order.

If the __reversed__() method is not provided, the reversed() built-in will fall back to using the sequence protocol (__len__() and __getitem__()). Objects that support the sequence protocol should only provide __reversed__() if they can provide an implementation that is more efficient than the one provided by reversed().

The membership test operators (in and not in) are normally implemented as an iteration through a sequence. However, container objects can supply the following special method with a more efficient implementation, which also does not require the object be a sequence.

object.__contains__(self, item)

Called to implement membership test operators. Should return true if item is in self, false otherwise. For mapping objects, this should consider the keys of the mapping rather than the values or the key-item pairs.

For objects that don’t define __contains__(), the membership test first tries iteration via __iter__(), then the old sequence iteration protocol via __getitem__(), see this section in the language reference.

3.3.7. Emulating numeric types

The following methods can be defined to emulate numeric objects. Methods corresponding to operations that are not supported by the particular kind of number implemented (e.g., bitwise operations for non-integral numbers) should be left undefined.

object.__add__(self, other)
object.__sub__(self, other)
object.__mul__(self, other)
object.__matmul__(self, other)
object.__truediv__(self, other)
object.__floordiv__(self, other)
object.__mod__(self, other)
object.__divmod__(self, other)
object.__pow__(self, other[, modulo])
object.__lshift__(self, other)
object.__rshift__(self, other)
object.__and__(self, other)
object.__xor__(self, other)
object.__or__(self, other)

These methods are called to implement the binary arithmetic operations (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |). For instance, to evaluate the expression x + y, where x is an instance of a class that has an __add__() method, x.__add__(y) is called. The __divmod__() method should be the equivalent to using __floordiv__() and __mod__(); it should not be related to __truediv__(). Note that __pow__() should be defined to accept an optional third argument if the ternary version of the built-in pow() function is to be supported.

If one of those methods does not support the operation with the supplied arguments, it should return NotImplemented.

object.__radd__(self, other)
object.__rsub__(self, other)
object.__rmul__(self, other)
object.__rmatmul__(self, other)
object.__rtruediv__(self, other)
object.__rfloordiv__(self, other)
object.__rmod__(self, other)
object.__rdivmod__(self, other)
object.__rpow__(self, other)
object.__rlshift__(self, other)
object.__rrshift__(self, other)
object.__rand__(self, other)
object.__rxor__(self, other)
object.__ror__(self, other)

These methods are called to implement the binary arithmetic operations (+, -, *, @, /, //, %, divmod(), pow(), **, <<, >>, &, ^, |) with reflected (swapped) operands. These functions are only called if the left operand does not support the corresponding operation 3 and the operands are of different types. 4 For instance, to evaluate the expression x - y, where y is an instance of a class that has an __rsub__() method, y.__rsub__(x) is called if x.__sub__(y) returns NotImplemented.

Note that ternary pow() will not try calling __rpow__() (the coercion rules would become too complicated).

Nota

If the right operand’s type is a subclass of the left operand’s type and that subclass provides the reflected method for the operation, this method will be called before the left operand’s non-reflected method. This behavior allows subclasses to override their ancestors’ operations.

object.__iadd__(self, other)
object.__isub__(self, other)
object.__imul__(self, other)
object.__imatmul__(self, other)
object.__itruediv__(self, other)
object.__ifloordiv__(self, other)
object.__imod__(self, other)
object.__ipow__(self, other[, modulo])
object.__ilshift__(self, other)
object.__irshift__(self, other)
object.__iand__(self, other)
object.__ixor__(self, other)
object.__ior__(self, other)

These methods are called to implement the augmented arithmetic assignments (+=, -=, *=, @=, /=, //=, %=, **=, <<=, >>=, &=, ^=, |=). These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self). If a specific method is not defined, the augmented assignment falls back to the normal methods. For instance, if x is an instance of a class with an __iadd__() method, x += y is equivalent to x = x.__iadd__(y) . Otherwise, x.__add__(y) and y.__radd__(x) are considered, as with the evaluation of x + y. In certain situations, augmented assignment can result in unexpected errors (see Porque a_tuple[i] += [‘item’] levanta uma exceção quando a adição funciona?), but this behavior is in fact part of the data model.

object.__neg__(self)
object.__pos__(self)
object.__abs__(self)
object.__invert__(self)

Called to implement the unary arithmetic operations (-, +, abs() and ~).

object.__complex__(self)
object.__int__(self)
object.__float__(self)

Called to implement the built-in functions complex(), int() and float(). Should return a value of the appropriate type.

object.__index__(self)

Called to implement operator.index(), and whenever Python needs to losslessly convert the numeric object to an integer object (such as in slicing, or in the built-in bin(), hex() and oct() functions). Presence of this method indicates that the numeric object is an integer type. Must return an integer.

Nota

In order to have a coherent integer type class, when __index__() is defined __int__() should also be defined, and both should return the same value.

object.__round__(self[, ndigits])
object.__trunc__(self)
object.__floor__(self)
object.__ceil__(self)

Called to implement the built-in function round() and math functions trunc(), floor() and ceil(). Unless ndigits is passed to __round__() all these methods should return the value of the object truncated to an Integral (typically an int).

If __int__() is not defined then the built-in function int() falls back to __trunc__().

3.3.8. With Statement Context Managers

A context manager is an object that defines the runtime context to be established when executing a with statement. The context manager handles the entry into, and the exit from, the desired runtime context for the execution of the block of code. Context managers are normally invoked using the with statement (described in section The with statement), but can also be used by directly invoking their methods.

Typical uses of context managers include saving and restoring various kinds of global state, locking and unlocking resources, closing opened files, etc.

For more information on context managers, see Tipos de Gerenciador de Contexto.

object.__enter__(self)

Enter the runtime context related to this object. The with statement will bind this method’s return value to the target(s) specified in the as clause of the statement, if any.

object.__exit__(self, exc_type, exc_value, traceback)

Exit the runtime context related to this object. The parameters describe the exception that caused the context to be exited. If the context was exited without an exception, all three arguments will be None.

If an exception is supplied, and the method wishes to suppress the exception (i.e., prevent it from being propagated), it should return a true value. Otherwise, the exception will be processed normally upon exit from this method.

Note that __exit__() methods should not reraise the passed-in exception; this is the caller’s responsibility.

Ver também

PEP 343 - The “with” statement

The specification, background, and examples for the Python with statement.

3.3.9. Special method lookup

For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary. That behaviour is the reason why the following code raises an exception:

>>> class C:
...     pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'C' has no len()

The rationale behind this behaviour lies with a number of special methods such as __hash__() and __repr__() that are implemented by all objects, including type objects. If the implicit lookup of these methods used the conventional lookup process, they would fail when invoked on the type object itself:

>>> 1 .__hash__() == hash(1)
True
>>> int.__hash__() == hash(int)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor '__hash__' of 'int' object needs an argument

Incorrectly attempting to invoke an unbound method of a class in this way is sometimes referred to as ‘metaclass confusion’, and is avoided by bypassing the instance when looking up special methods:

>>> type(1).__hash__(1) == hash(1)
True
>>> type(int).__hash__(int) == hash(int)
True

In addition to bypassing any instance attributes in the interest of correctness, implicit special method lookup generally also bypasses the __getattribute__() method even of the object’s metaclass:

>>> class Meta(type):
...     def __getattribute__(*args):
...         print("Metaclass getattribute invoked")
...         return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print("Class getattribute invoked")
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10

Bypassing the __getattribute__() machinery in this fashion provides significant scope for speed optimisations within the interpreter, at the cost of some flexibility in the handling of special methods (the special method must be set on the class object itself in order to be consistently invoked by the interpreter).

3.4. Coroutines

3.4.1. Awaitable Objects

An awaitable object generally implements an __await__() method. Coroutine objects returned from async def functions are awaitable.

Nota

The generator iterator objects returned from generators decorated with types.coroutine() or asyncio.coroutine() are also awaitable, but they do not implement __await__().

object.__await__(self)

Must return an iterator. Should be used to implement awaitable objects. For instance, asyncio.Future implements this method to be compatible with the await expression.

Novo na versão 3.5.

Ver também

PEP 492 for additional information about awaitable objects.

3.4.2. Objetos Coroutine

Coroutine objects are awaitable objects. A coroutine’s execution can be controlled by calling __await__() and iterating over the result. When the coroutine has finished executing and returns, the iterator raises StopIteration, and the exception’s value attribute holds the return value. If the coroutine raises an exception, it is propagated by the iterator. Coroutines should not directly raise unhandled StopIteration exceptions.

Coroutines also have the methods listed below, which are analogous to those of generators (see Generator-iterator methods). However, unlike generators, coroutines do not directly support iteration.

Alterado na versão 3.5.2: It is a RuntimeError to await on a coroutine more than once.

coroutine.send(value)

Starts or resumes execution of the coroutine. If value is None, this is equivalent to advancing the iterator returned by __await__(). If value is not None, this method delegates to the send() method of the iterator that caused the coroutine to suspend. The result (return value, StopIteration, or other exception) is the same as when iterating over the __await__() return value, described above.

coroutine.throw(type[, value[, traceback]])

Raises the specified exception in the coroutine. This method delegates to the throw() method of the iterator that caused the coroutine to suspend, if it has such a method. Otherwise, the exception is raised at the suspension point. The result (return value, StopIteration, or other exception) is the same as when iterating over the __await__() return value, described above. If the exception is not caught in the coroutine, it propagates back to the caller.

coroutine.close()

Causes the coroutine to clean itself up and exit. If the coroutine is suspended, this method first delegates to the close() method of the iterator that caused the coroutine to suspend, if it has such a method. Then it raises GeneratorExit at the suspension point, causing the coroutine to immediately clean itself up. Finally, the coroutine is marked as having finished executing, even if it was never started.

Coroutine objects are automatically closed using the above process when they are about to be destroyed.

3.4.3. Iteradores Assíncronos

An asynchronous iterable is able to call asynchronous code in its __aiter__ implementation, and an asynchronous iterator can call asynchronous code in its __anext__ method.

Asynchronous iterators can be used in an async for statement.

object.__aiter__(self)

Must return an asynchronous iterator object.

object.__anext__(self)

Must return an awaitable resulting in a next value of the iterator. Should raise a StopAsyncIteration error when the iteration is over.

An example of an asynchronous iterable object:

class Reader:
    async def readline(self):
        ...

    def __aiter__(self):
        return self

    async def __anext__(self):
        val = await self.readline()
        if val == b'':
            raise StopAsyncIteration
        return val

Novo na versão 3.5.

Nota

Alterado na versão 3.5.2: Starting with CPython 3.5.2, __aiter__ can directly return asynchronous iterators. Returning an awaitable object will result in a PendingDeprecationWarning.

The recommended way of writing backwards compatible code in CPython 3.5.x is to continue returning awaitables from __aiter__. If you want to avoid the PendingDeprecationWarning and keep the code backwards compatible, the following decorator can be used:

import functools
import sys

if sys.version_info < (3, 5, 2):
    def aiter_compat(func):
        @functools.wraps(func)
        async def wrapper(self):
            return func(self)
        return wrapper
else:
    def aiter_compat(func):
        return func

Exemplo:

class AsyncIterator:

    @aiter_compat
    def __aiter__(self):
        return self

    async def __anext__(self):
        ...

Starting with CPython 3.6, the PendingDeprecationWarning will be replaced with the DeprecationWarning. In CPython 3.7, returning an awaitable from __aiter__ will result in a RuntimeError.

3.4.4. Asynchronous Context Managers

An asynchronous context manager is a context manager that is able to suspend execution in its __aenter__ and __aexit__ methods.

Asynchronous context managers can be used in an async with statement.

object.__aenter__(self)

This method is semantically similar to the __enter__(), with only difference that it must return an awaitable.

object.__aexit__(self, exc_type, exc_value, traceback)

This method is semantically similar to the __exit__(), with only difference that it must return an awaitable.

An example of an asynchronous context manager class:

class AsyncContextManager:
    async def __aenter__(self):
        await log('entering context')

    async def __aexit__(self, exc_type, exc, tb):
        await log('exiting context')

Novo na versão 3.5.

Notas de Rodapé

1

It is possible in some cases to change an object’s type, under certain controlled conditions. It generally isn’t a good idea though, since it can lead to some very strange behaviour if it is handled incorrectly.

2

The __hash__(), __iter__(), __reversed__(), and __contains__() methods have special handling for this; others will still raise a TypeError, but may do so by relying on the behavior that None is not callable.

3

“Does not support” here means that the class has no such method, or the method returns NotImplemented. Do not set the method to None if you want to force fallback to the right operand’s reflected method—that will instead have the opposite effect of explicitly blocking such fallback.

4

For operands of the same type, it is assumed that if the non-reflected method (such as __add__()) fails the operation is not supported, which is why the reflected method is not called.