
Atributos Python: entendendo como funcionam 🐍
Atributos são a base do modelo de objetos do Python, mas a maioria dos iniciantes (e até muitos plenos) os usam intuitivamente, sem entender o que acontece "debaixo do capô". O resultado: comportamento imprevisível do código, consumo de memória e APIs espaguete.
Vamos entender os detalhes 👇
1️⃣ Ordem de busca (MRO)
Python vive pelo princípio: primeiro o objeto, depois a classe.
Quando você acessa
obj.attr, o interpretador primeiro olha em obj.__dict__. Se não encontrar, vai para Class.__dict__.Se você acidentalmente escrever algo em
obj.attr, criará um atributo de instância que ocultará o atributo de classe.class Hero:
weapon = "Sword"
h = Hero()
h.weapon = "Gun" # Agora h tem sua própria arma, a classe ainda tem a espadaIsso não é um bug, é uma feature, mas controle isso. Se quiser alterar o atributo para todos — mexa na classe.
2️⃣
__dict__ vs __slots__Por padrão, cada objeto tem
__dict__ — uma tabela hash (dicionário) onde os atributos são armazenados. Isso é flexível, mas caro em memória.Se você cria milhões de objetos do mesmo tipo, use
__slots__.🔵O que isso faz: Impede a criação de
__dict__ para a instância, fixando rigidamente o conjunto de atributos na memória (como um array).🔵Benefício: Redução de 25-30% no consumo de memória e acesso um pouco mais rápido.
🔵Custo: Você perde a capacidade dinâmica de adicionar novos atributos em tempo de execução.
3️⃣ A ilusão de encapsulamento
Em Python não existem campos "privados". De jeito nenhum.
Construções como
__attribute não são proteção de dados, mas sim name mangling (distorção de nomes). Python simplesmente renomeia a variável para _ClassName__attribute para evitar sobrescrita acidental em subclasses.Se você usa
__ esperando que ninguém acesse seus dados, qualquer um que saiba usar dir() verá tudo. Usar _private (um sublinhado) significa "não mexa, é uma API interna". É uma questão de cultura, não de compilador.Quer ocultar dados? Use um sublinhado inferior
_ apenas como sinal para colegas: "Não mexa nisso, é parte interna".4️⃣ @property: o getter ético
Nunca faça getters no estilo Java em Python (
get_value(), set_value()). Se precisar de lógica ao acessar um atributo, use @property.@property permite transformar um método em um atributo. Você mantém uma API limpa (acesso por ponto), mas por baixo dos panos pode validar dados, registrar acesso ou calcular valores em tempo real.class DataStorage:
def __init__(self, value):
self._value = value
@property
def value(self):
return self._value
@value.setter
def value(self, new_val):
if not isinstance(new_val, int):
raise ValueError("Só int, querido")
self._value = new_valAssim você mantém uma interface limpa:
obj.value = 10 parece tão simples quanto trabalhar com um campo comum, mas você controla o que é realmente escrito.Que outros lugares "mágicos" do Python geram dúvidas em vocês? Mandem nos comentários, vamos analisar. 👇
#anatomia_do_python
Comentários
0Ainda não há comentários.
Entre para participar da conversa.