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: representa o endereço do objeto em memória. Consultada com
id(nome_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 visto anteriormente, a identidade de um objeto refere-se ao seu endereço de memória: id(x) retorna um int representando o espaço de memória em que x está armazenado. Já a igualdade verifica se os valores de dois objetos são iguais, utilizando o método mágico __eq__ — voltaremos a estudar mais sobre este método nos próximos capítulos.
-
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 em Python compreende quatro fases principais: criação e alocação de memória, inicialização de atributos, uso ativo no programa por meio de referências, e destruição com liberação de memória controlada por contagem de referências e coletor de lixo.
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
Quando um objeto se torna inacessível — ou seja, quando sua contagem de referências chega a zero — ele pode ser coletado como lixo pelo CPython através de um esquema de contagem de referências, com detecção atrasada para referências circulares. Essa coleta cíclica é opcional e não garante que todo o lixo com referências circulares será efetivamente coletado.
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 de maneira eficiente — verificação essa que, internamente, usa igualdade (==), não identidade.
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 é o que sustenta o próximo passo da série: os métodos mágicos (dunder methods), o protocolo que Python usa por trás de operações aparentemente simples como len(obj), obj[chave] ou for item in obj. Na Parte 2, vamos ver como esses métodos permitem que objetos criados por você se comportem como os tipos nativos da linguagem.
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)