Os "dunder methods" (de "double underscore" - dois sublinhados) são métodos especiais em Python que você não chama diretamente, mas que são invocados automaticamente pelo Python em certas situações. Eles permitem que suas classes interajam com funcionalidades e sintaxes built-in do Python de uma forma muito poderosa e intuitiva.
Pense neles como "ganchos" que você pode implementar em suas classes para que elas se comportem como os tipos de dados nativos do Python (como listas, strings, números, etc.) ou para definir um comportamento padrão para operações comuns.
Para que servem EXATAMENTE?
Eles servem para:
+
? Ou comparado com ==
? Ou que possa ser iterado com um for
? Os dunder methods são a forma de fazer isso.print()
em um objeto, o Python chama o __str__
dele. Se você não definir __str__
, ele terá uma saída padrão genérica. Com o dunder method, você personaliza essa saída.Vamos esmiuçar os exemplos que você viu, focando no "para que serve" de cada um:
__init__(self, ...)
: O "Construtor"O que faz: É o primeiro método a ser executado automaticamente sempre que você cria uma nova instância de uma classe.
Para que serve: Serve para inicializar o estado de um objeto. É onde você geralmente define os atributos iniciais do objeto.
class Pessoa:
def __init__(self, nome, idade): # Quando Pessoa() é chamado, __init__ é invocado
self.nome = nome # Inicializa o atributo 'nome' da instância
self.idade = idade # Inicializa o atributo 'idade' da instância
p = Pessoa("Maria", 30) # Ao criar o objeto 'p', __init__ é chamado.
print(p.nome) # Saída: Maria
__str__(self)
: A Representação "Amigável" para UsuáriosO que faz: Define o que deve ser retornado quando o objeto é convertido para string de uma forma "legível para humanos".
Para que serve:
print(objeto)
.str(objeto)
.class Produto:
def __init__(self, nome, preco):
self.nome = nome
self.preco = preco
def __str__(self): # Define o que 'print(p)' vai mostrar
return f"Produto: {self.nome} (R${self.preco:.2f})"
p = Produto("Notebook", 2500.00)
print(p) # Saída: Produto: Notebook (R$2500.00) - Chama __str__
s_p = str(p) # s_p recebe "Produto: Notebook (R$2500.00)" - Chama __str__
print(s_p)
__repr__(self)
: A Representação "Oficial" para DesenvolvedoresO que faz: Define a representação "oficial" (canônica) de um objeto. O objetivo é que essa string, se copiada e colada, possa recriar o objeto.
Para que serve: Geralmente, __repr__
é implementado primeiro, e se __str__
não for implementado, __str__
usa o __repr__
por padrão.
str()
não é definido, o print()
tenta usar __repr__
.class Produto:
def __init__(self, nome, preco):
self.nome = nome
self.preco = preco
def __repr__(self): # Define o que o objeto vai mostrar no console ou em debugging
return f"Produto(nome='{self.nome}', preco={self.preco:.2f})"
p = Produto("Notebook", 2500.00)
print(p) # Se __str__ não estivesse definido, ele chamaria __repr__ aqui.
# Se __str__ ESTIVER definido, ele chama __str__ aqui.
print(repr(p)) # Saída: Produto(nome='Notebook', preco=2500.00) - Chama __repr__
__eq__(self, other)
: Comparação de Igualdade (==
)==
(igual a) deve funcionar para objetos da sua classe.