Python / Objetos e variáveis

No Python, um objeto representa dados com valor e operações possíveis; uma variável é um nome ligado a um objeto. x = 100 liga x a um inteiro, e outra atribuição muda o objeto referenciado. Atribuir não copia objetos automaticamente: vários nomes podem compartilhar a mesma lista.

Nomes, objetos e tipos

O modelo de dados do Python descreve identidade, tipo e valor como propriedades dos objetos. O tipo define operações e características. A identidade permanece durante a vida do objeto; a possibilidade de alterar seu valor depende do tipo. Pensar em uma variável como uma caixa de tipo fixo dificulta explicar reatribuição e compartilhamento.

Os exemplos usam Python 3 e a biblioteca padrão, e suas saídas foram verificadas com Python 3.12.14. Salve cada código completo em UTF-8 como objects_demo.py e execute python objects_demo.py no terminal, ou python3 conforme o ambiente. Substitua o conteúdo para testar cada exemplo de forma independente.

value = 100
print(value, type(value).__name__)
value = "hello"
print(value, type(value).__name__)
100 int
hello str

value primeiro referencia um int e depois um str. O inteiro 100 não mudou seu próprio tipo. Uma atribuição avalia a expressão à direita e liga o resultado ao nome à esquerda. type(value) consulta o tipo do objeto atualmente referenciado.

Compartilhar uma lista ou reatribuir um nome

second = first não cria uma cópia: os dois nomes referenciam a mesma lista. Compare alterar esse objeto compartilhado com ligar somente um nome a outro objeto:

first = [1, 2]
second = first
second.append(3)
print(first)
print(second)
print(first is second)
first = [0]
print(first)
print(second)
print(first is second)
[1, 2, 3]
[1, 2, 3]
True
[0]
[1, 2, 3]
False

append altera a lista compartilhada, então first também mostra o 3 acrescentado. Já first = [0] liga apenas first a uma lista nova. second continua referenciando a anterior. Diferencie a ligação de um nome do conteúdo do objeto.

Operação Significado Efeito no outro nome
second = first Acrescentar nome para o mesmo objeto Ambos observam alterações posteriores
second.append(3) Alterar a lista A mesma lista mostra o conteúdo alterado
first = [0] Ligar first a outro objeto second mantém sua ligação

Objetos imutáveis e +=

Inteiros, strings e tuplas são imutáveis; listas e dicionários são mutáveis. Imutável significa que o objeto não pode ser alterado no próprio lugar, não que seu nome esteja impedido de receber outra atribuição.

first = 10
second = first
first += 1
print(first)
print(second)
11
10

O inteiro 10 não foi transformado em 11. first passa a referenciar o resultado da soma e second continua em 10. Com listas, a mesma sintaxe += pode alterar o objeto existente; não generalize seu comportamento entre tipos. As referências dos itens de uma tupla não podem ser substituídas, mas uma lista contida nela pode mudar de conteúdo.

Escolher a profundidade da cópia

copy() de uma lista cria uma nova lista externa: uma cópia rasa. Os objetos internos continuam compartilhados. Compare com copy.deepcopy() usando os mesmos dados iniciais:

from copy import deepcopy

original = [[1], [2]]
shallow = original.copy()
deep = deepcopy(original)
shallow[0].append(9)
shallow.append([3])
print(original)
print(shallow)
print(deep)
print(original is shallow)
print(original[0] is shallow[0])
[[1, 9], [2]]
[[1, 9], [2], [3]]
[[1], [2]]
False
True

Adicionar 9 à lista interna por shallow também aparece em original. Acrescentar [3] à lista externa de shallow não aumenta o tamanho de original. deep mantém uma cópia independente do conteúdo aninhado inicial. Decida se o compartilhamento é intencional e copie apenas o necessário. A cópia profunda tem custo e não duplica arquivos ou sockets como dados comuns.

== compara igualdade; is, identidade

Nas listas nativas, == compara conteúdo e is verifica se é exatamente o mesmo objeto. As listas abaixo foram criadas separadamente, embora tenham conteúdo igual:

left = [1, 2]
right = [1, 2]
alias = left
print(left == right)
print(left is right)
print(left is alias)
print(id(left) == id(alias))
missing = None
print(missing is None)
True
False
True
True
True

Use os operadores de comparação conforme a finalidade. id() retorna um inteiro que representa identidade; o número concreto pode mudar entre execuções e não é necessariamente um endereço de memória em todas as implementações. Não compare valores de números ou strings com is contando com cache ou reutilização. Use == para valores e is None para verificar None.

del remove a ligação de um nome

del é uma instrução, não uma função. del first remove essa ligação. Se outro nome continuar referenciando o objeto, ele permanece utilizável:

first = [1, 2]
second = first
del first
print(second)
try:
    print(first)
except NameError:
    print("first: NameError")
try:
    del unknown_name
except NameError:
    print("unknown_name: NameError")
[1, 2]
first: NameError
unknown_name: NameError

second ainda imprime a lista, enquanto acessar first gera NameError. Excluir um nome desconhecido também gera NameError. Dependendo do alvo, a instrução del pode excluir itens ou atributos, não apenas nomes. Remover uma ligação não garante destruir imediatamente o objeto ou liberar a memória. Feche arquivos com with ou close em vez de depender de del.

Nomes válidos e legíveis

Com caracteres latinos básicos, comece com letra ou sublinhado e use dígitos depois. Espaços e hífens não são permitidos, e maiúsculas são diferentes de minúsculas. Python também permite determinados caracteres Unicode; os identificadores não se limitam ao inglês.

import keyword

for name in ["user_name", "2name", "class", "first-name", "café", "match"]:
    valid = name.isidentifier() and not keyword.iskeyword(name)
    print(name, valid)
print("match soft keyword:", keyword.issoftkeyword("match"))
user_name True
2name False
class False
first-name False
café True
match True
match soft keyword: True

isidentifier() aceita o formato de class; portanto, consulte também keyword.iskeyword(). Neste ambiente, match é uma palavra-chave contextual, não uma palavra reservada em todos os usos. Veja a gramática de identificadores e palavras-chave. As listas podem mudar por versão: use o módulo keyword do interpretador atual.

Mesmo válidos, nomes como list ou str podem ocultar funções nativas e dificultar seu uso. Prefira nomes que revelem a função do valor, como user_name e item_count. Ao encontrar NameError, confira maiúsculas, atribuição anterior e escopo onde o nome está disponível.