Método __new__
# Exemplo básico de __new__
class ExemploBase:
def __new__(cls):
print(f"Classe recebida: {cls}")
return object.__new__(cls)
objeto = ExemploBase()
# Demonstração da ordem de execução
class Demonstracao:
def __new__(cls):
print("1: Criação do objeto")
return object.__new__(cls)
def __init__(self):
print("2: Inicialização do objeto")
instancia = Demonstracao()
# Passando parâmetros
class Parametros:
def __new__(cls, valor, *args, **kwargs):
return object.__new__(cls)
def __init__(self, valor, extra=None):
self.dado = valor
self.complemento = extra
param = Parametros(10, extra="info")
# Importante: Se __new__ não retornar a instância atual, __init__ não será chamado
class SemInit:
def __new__(cls):
return None # __init__ não será executado
teste = SemInit()
print(type(teste)) # Output: NoneType
# Implementação do Singleton
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
a = Singleton()
b = Singleton()
print(f"Mesma instância? {a is b}")
# Singleton com inicialização de atributos
class GerenciadorConexao:
_instance = None
def __new__(cls, url):
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance.url = url
return cls._instance
def conectar(self):
return f"Conectado a {self.url}"
conexao1 = GerenciadorConexao("db://principal")
conexao2 = GerenciadorConexao("db://secundaria")
print(conexao1.conectar()) # Apenas a primeira URL é mantida
# Exemplo de destrutor
class Recurso:
def __init__(self, nome):
self.nome = nome
self.arquivo = open(f"{nome}.txt", "w")
def escrever(self, texto):
self.arquivo.write(texto)
def __del__(self):
self.arquivo.close()
print(f"Recurso '{self.nome}' liberado")
# Quando o objeto é destruído
recurso = Recurso("temp")
recurso.escrever("dados")
recurso = None # __del__ será chamado aqui
# Controle de referências
obj1 = Recurso("dados")
obj2 = obj1
del obj1 # Não destrói ainda, pois obj2 ainda referencia
obj2 = None # Agora __del__ é chamado
# Usando objetos como funções
class Calculadora:
def __call__(self, a, b):
return a + b
calc = Calculadora()
resultado = calc(3, 4) # Executa __call__
# Encadeamento de operações
class Pipeline:
def __init__(self):
self.etapas = []
def adicionar(self, funcao):
self.etapas.append(funcao)
return self
def __call__(self, valor):
resultado = valor
for etapa in self.etapas:
resultado = etapa(resultado)
return resultado
processamento = Pipeline()
processamento.adicionar(lambda x: x * 2).adicionar(lambda x: x + 1)
print(processamento(5)) # Output: 11
# Representação para debug (repr)
class Ponto:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Ponto({self.x}, {self.y})"
# Representação para usuário (str)
class Usuario:
def __init__(self, nome, email):
self.nome = nome
self.email = email
def __str__(self):
return self.nome
def __repr__(self):
return f"Usuario('{self.nome}', '{self.email}')"
p = Ponto(2, 3)
print(repr(p)) # Output: Ponto(2, 3)
u = Usuario("Ana", "ana@email.com")
print(u) # Output: Ana (usa __str__)
print(repr(u)) # Output: Usuario('Ana', 'ana@email.com') (usa __repr__)
def adicionar(self, item):
self.itens.append(item)
def __bool__(self):
return len(self.itens) > 0
carrinho = Carrinho() print(bool(carrinho)) # Output: False (carrinho vazio) carrinho.adicionar("produto") print(bool(carrinho)) # Output: True
Métodos add e radd
class Vetor: def init(self, x, y): self.x = x self.y = y
def __add__(self, outro):
return Vetor(self.x + outro.x, self.y + outro.y)
def __radd__(self, outro):
if isinstance(outro, (int, float)):
return Vetor(self.x + outro, self.y + outro)
return NotImplemented
v1 = Vetor(1, 2) v2 = Vetor(3, 4) v3 = v1 + v2 # Usa add v4 = 5 + v1 # Usa radd print(f"Soma vetores: ({v3.x}, {v3.y})") print(f"Soma escalar: ({v4.x}, {v4.y})")
Método len
class Colecao: def init(self, dados): self._dados = list(dados)
def __len__(self):
return len(self._dados)
colet = Colecao([1, 2, 3, 4]) print(f"Tamanho: {len(colet)}") # Output: 4
</div>