Métodos especiais
Definição
Python considera que uma classe pode ter dois tipos de métodos: métodos criados pelo programador e métodos especiais que são embutidos na linguagem.
Métodos especiais são identificados por um sublinhado duplo em cada lado do nome, como __new__ e __init__. Esse tipo de método é chamado automaticamente, quando necessário, pelo programa. Por exemplo, quando um novo objeto é criado, o Python chama automaticamente o método __new__, que por sua vez chama o método __init__.
Não é possível chamar os métodos especiais explicitamente no programa, mas é possível alterá-los dentro das classes. O exemplo abaixo altera o método especial __add__ para a operação “+” e o método especial __init__ para a inicialização das variáveis. Essas alterações são válidas apenas para objetos da classe Valor.
class Valor:
def __init__(self, valor):
print("Inicializa variável com", valor)
self.valor = valor
def __add__(self, outro):
print("Valores somados:", self.valor, "e", outro.valor)
return Valor(self.valor + outro.valor)
a = Valor(15)
b = Valor(8)
c = a + b
print("Resultado =", c.valor)
A resposta do programa é:
Inicializa variável com 15 Inicializa variável com 8 Valores somados: 15 e 8 Inicializa variável com 23 Resultado = 23
Para mais detalhes sobre métodos especiais, veja https://docs.python.org/3/reference/datamodel.html#special-method-names.
Exemplos
- Exemplo: Definir uma classe e criar um objeto dessa classe no Python é bastante simples. O script abaixo define a classe Aluno e depois cria o objeto aluno da classe Aluno.
class Aluno:
nome = "Maria Flor"
aluno = Aluno()
print("Nome = ", aluno.nome)
A saída do programa é:
Nome = Maria Flor
Quando a instância de uma classe é criada, o Python chama primeiro o método __new__() para criar o objeto e, em seguida, chama o método __init__() para inicializar os atributos do objeto. Para alterar esses métodos, basta a classe defini-los dentro do seu escopo.
class Aluno:
def __new__(cls, name):
print(f'1 - Cria um novo objeto {cls.__name__}')
objeto = object.__new__(cls)
return objeto
def __init__(self, nome):
print('2 - Inicializa o objeto')
self.nome = nome
aluno = Aluno('Maria Flor')
print("Nome =", aluno.nome)
Observe que a função __name__ é usada para obter o nome da classe. Abaixo a resposta do programa.
1 - Cria um novo objeto Aluno 2 - Inicializa o objeto Nome = Maria Flor
- Exemplo: a função __del__ pode ser usada para deletar objetos ou atributos de objetos.
class Aluno:
def __init__(self, nome, curso):
self.nome = nome
self.curso = curso
def __del__(self):
print('Atributo deletado')
aluno = Aluno("Maria Flor", "BSI")
print("Antes da deleção:", vars(aluno))
del aluno.curso
print("Depois da deleção", vars(aluno))
A saída do programa é mostrada abaixo.
Antes da deleção: {'nome': 'Maria Flor', 'curso': 'BSI'}
Depois da deleção {'nome': 'Maria Flor'}
Atributo deletado
- Exemplo: o programa conta o número de objetos da classe Aluno que existe no ambiente.
class Aluno:
contador = 0
def __init__(self, nome, curso):
self.nome = nome
self.curso = curso
type(self).contador += 1
def __del__(self):
type(self).contador -= 1
print('Aluno deletado:', self.nome)
aluno1 = Aluno("Maria Flor", "BSI")
aluno2 = Aluno("João Pedro", "BSI")
aluno3 = Aluno("Ana Clara", "BSI")
aluno4 = Aluno("Carlos Luiz", "BSI")
print("Número inicial de alunos =", Aluno.contador)
del aluno2
print("Número final de alunos =", Aluno.contador)
print("*** Fim do programa")
A resposta do programa é mostrada abaixo. Note que após da execução da última linha do programa, os objetos da classe Aluno, que ainda existem, são deletados.
Número inicial de alunos = 4 Aluno deletado: João Pedro Número final de alunos = 3 *** Fim do programa Aluno deletado: Maria Flor Aluno deletado: Ana Clara Aluno deletado: Carlos Luiz
- Exemplo: verifica o tamanho do atributo nome da classe Aluno.
class Aluno:
def __init__(self, nome):
self.nome = nome
self.tam = len(self.nome)
def __len__(self):
print("*** Verifica tamanho do nome")
return self.tam
aluno = Aluno("Maria Flor")
print("1 - Tamanho =", len(aluno))
print("2 - Tamanho =", len(aluno.nome))
A saída do programa é apresentada abaixo. Observe que __len__ espera um objeto da classe Aluno. No primeiro caso, quando o programa chama len(aluno), a função __len__ é executada. No segundo caso, quando o programa chama len(aluno.nome), a função embutida len() é executada, pois uma string é fornecida como argumento.
*** Verifica tamanho do nome 1 - Tamanho = 10 2 - Tamanho = 10
