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