Read this article in English here.
1. Introdução
Se você já se perguntou por que alterar uma lista dentro de uma função muda a lista original, mas alterar um número não, você esbarrou em um dos conceitos mais fundamentais (e mais mal compreendidos) de Python: o modelo de dados da linguagem.
Entender como Python representa, identifica e compara objetos não é só teoria: é o que evita bugs sutis relacionados a aliasing, comparações incorretas e efeitos colaterais inesperados em containers mutáveis.
Neste primeiro artigo da série, vamos construir a base necessária para isso: o que é um objeto em Python, a diferença entre identidade e igualdade, o que realmente significa mutabilidade, como um objeto nasce e morre, e como tudo isso se conecta quando objetos são armazenados em containers.
Este artigo assume que você já tem familiaridade com a sintaxe básica de Python (variáveis, listas, dicionários, funções). Se esse é o seu caso, vamos direto ao ponto.
2. Tudo é objeto
O modelo de dados define como os valores são representados e como se comportam em Python. Todo dado manipulado pelo programa é um objeto: números, strings, listas, funções, classes e até módulos (PYTHON SOFTWARE FOUNDATION, 2026a).
Um objeto Python conta com três características essenciais:
- Identidade: distingue um objeto de todos os outros e permanece a mesma durante toda a sua existência. Pode ser consultada com id(nome_objeto). No CPython, especificamente, id() corresponde ao endereço de memória do objeto.
-
Tipo: define quais valores e operações o objeto aceita. Consultado com
type(nome_objeto). - Valor: conteúdo representado pelo objeto, podendo ou não ser alterado a depender da mutabilidade do objeto.
Os tipos afetam quase todos os aspectos do comportamento do objeto. Isso vale até para a identidade: alguns tipos possuem uma única instância em todo o programa, e por isso a forma correta de compará-los é por identidade (is), não por igualdade (==):
-
Nonerepresenta ausência de valor; -
NotImplementedinforma que uma operação especial não oferece suporte aos operandos recebidos; -
..., também chamado deEllipsis, pode ser usado como uma sentinela e em operações especiais de fatiamento.
type(None) # <class 'NoneType'>
type(NotImplemented) # <class 'NotImplementedType'>
type(...) # <class 'ellipsis'>
Para instâncias únicas, o operador is é sempre a forma recomendada de checar ausência de valor:
x == None # ERRADO
x is None # CORRETO
3. Identidade vs Igualdade
Como vimos, a identidade distingue um objeto de todos os demais e permanece estável durante sua existência. id(x) retorna um inteiro que representa essa identidade; no CPython, especificamente, esse valor corresponde ao endereço de memória do objeto. Igualdade, por outro lado, verifica a relação de valor definida entre dois objetos através de == — comportamento que pode ser customizado por eq, um dos métodos especiais que veremos nas próximas partes.
-
is: compara identidades. -
==: compara conteúdo ou valores.
Essa distinção entre identidade e igualdade é a base para entender mutabilidade.
4. Mutável vs Imutável
A mutabilidade de um objeto é determinada pelo seu tipo. Um objeto mutável pode ter seu valor alterado depois de criado. Um objeto imutável não pode ser modificado; uma operação sobre ele produz outro objeto (PYTHON SOFTWARE FOUNDATION, 2026b).
| Imutáveis | Mutáveis |
|---|---|
NoneType |
list |
bool |
dict |
int, float, complex
|
set |
str, tuple, range
|
bytearray |
bytes, frozenset
|
A mutação altera o próprio objeto; a reatribuição faz o nome apontar para um novo objeto.
Exemplo com objeto mutável:
items = ['a', 'b'] # list é mutável
alias = items
items.append('c')
items # ['a', 'b', 'c']
alias # ['a', 'b', 'c']
Exemplo com objeto imutável:
total = 10 # int é imutável
alias = total
total += 5 # um novo objeto com valor 15 é criado; total passa a apontar para ele
total # 15
alias # 10
Objetos imutáveis podem conter referências a objetos mutáveis, pois a imutabilidade em Python afeta apenas a estrutura de referências do objeto, não o conteúdo interno ao qual ele aponta.
record = ("Alyne", ["Python"])
record[1].append("SQL")
record # ("Alyne", ["Python", "SQL"])
A tupla record continua apontando para as mesmas referências — apenas a lista interna foi alterada.
5. Ciclo de vida dos objetos
O ciclo de vida de um objeto começa com sua criação e continua enquanto ele puder ser alcançado pelo programa através de referências. Quando um objeto deixa de ser alcançável, ele pode se tornar elegível para coleta, mas Python não garante que essa liberação aconteça imediatamente.
No CPython, especificamente, o gerenciamento de memória utiliza principalmente contagem de referências, complementada por um garbage collector capaz de detectar ciclos de referências. Por isso, muitos objetos são liberados assim que deixam de possuir referências, enquanto ciclos podem exigir uma etapa adicional de coleta. Esse é um detalhe da implementação CPython, não uma garantia geral da linguagem.
Podemos observar parte deste comportamento no CPython com:
import sys
a = [1, 2, 3]
sys.getrefcount(a) # número de referências ativas ao objeto (inclui a referência temporária do próprio getrefcount)
b = a # nova referência para o mesmo objeto
sys.getrefcount(a) # o valor aumenta, pois agora 'a' e 'b' apontam para o mesmo objeto
6. Containers
Objetos containers são estruturas de dados capazes de armazenar outros objetos, ou seja, são objetos que contêm referências a outros.
Eles podem guardar dados de tipos diferentes ao mesmo tempo, permitem percorrer seus elementos usando laços de repetição, e é muito comum utilizar o operador in para verificar se um item está presente em um container. A forma exata dessa busca depende do tipo e dos protocolos que ele implementa (comportamento que aprofundaremos nas próximas partes).
Tipos principais de containers:
-
Listas (
list): sequências ordenadas e mutáveis, definidas por colchetes[]. -
Tuplas (
tuple): sequências ordenadas e imutáveis, definidas por parênteses(). -
Dicionários (
dict): coleções de pares chave-valor, definidos por chaves{}. -
Conjuntos (
set): coleções de elementos únicos e não ordenados, também definidos por chaves{}.
Atenção a uma pegadinha comum: {} vazio cria um dict, não um set. Para criar um conjunto vazio, é preciso usar set() explicitamente.
Como containers guardam referências e não cópias, tudo o que vimos sobre identidade, igualdade e mutabilidade se aplica de forma direta aqui: alterar um objeto mutável dentro de um container afeta todas as variáveis que referenciam esse mesmo objeto — mesmo que o container em si seja imutável, como vimos no exemplo da tupla na seção 4.
7. Conclusão
Identidade, igualdade, mutabilidade, ciclo de vida e containers são faces do mesmo conceito central: em Python, variáveis são referências a objetos, não caixas que guardam valores. Entender isso é o que permite prever, com segurança, quando uma alteração vai se propagar e quando vai gerar um objeto novo.
Essa base sustenta o próximo passo da série: entender como os métodos especiais permitem que nossos tipos participem dos protocolos da própria linguagem. Na Parte 2, veremos o que existe por trás de operações como len(obj), da criação e finalização de instâncias, da sobrecarga de operadores, do acesso a atributos e das representações produzidas por repr() e str().
Referências
PYTHON SOFTWARE FOUNDATION. 3. Modelo de dados. In: Documentação Python 3.14.6. [S. l.]: Python Software Foundation, 2026a. Disponível em: https://docs.python.org/pt-br/3/reference/datamodel.html. Acesso em: 28 jul. 2026.
PYTHON SOFTWARE FOUNDATION. Tipos embutidos. In: Documentação Python 3.14.6. [S. l.]: Python Software Foundation, 2026b. Disponível em: https://docs.python.org/pt-br/3/library/stdtypes.html. Acesso em: 28 jul. 2026.
Top comments (0)