Capítulo 26, Intermediário
Classes e objetos
Uma classe agrupa dados e comportamento que pertencem juntos. Eu mostro o essencial e, principalmente, quando **não** criar uma.
Código deste capítulo: intermediario/cap26_classes.py
A classe é o molde, o objeto é a coisa
Uma classe descreve como são e o que fazem os objetos de um tipo. Cada objeto criado a partir dela é uma instância, com os seus próprios dados:
class Cachorro:
def __init__(self, nome, idade):
self.nome = nome
self.idade = idade
def latir(self):
return f"{self.nome} diz: au au"
rex = Cachorro("Rex", 3)
mel = Cachorro("Mel", 5)
print(rex.nome, mel.nome)
print(rex.latir())
Rex Mel
Rex diz: au au
O __init__ é o inicializador: ele roda logo depois que o objeto é criado e prepara os dados iniciais. (Quem de fato cria o objeto é o __new__, que você raramente escreve.) A palavra self é o próprio objeto, e é por ela que cada método sabe de quem são os dados.
O que o self realmente é
Uma chamada como rex.latir() é só açúcar para Cachorro.latir(rex). O Python passa o objeto como primeiro argumento. Ver isso uma vez desfaz o mistério do self:
print(Cachorro.latir(mel))
print(type(rex).__name__, isinstance(rex, Cachorro))
Mel diz: au au
Cachorro True
Uma representação que ajuda a depurar
Imprimir um objeto sem __repr__ mostra algo como <Ponto object at 0x...>, que não ajuda ninguém. Defina o __repr__ em quase toda classe: ele deve mostrar os dados e, de preferência, parecer o código que recria o objeto:
class Ponto:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Ponto(x={self.x}, y={self.y})"
p = Ponto(1, 2)
print(p)
print(vars(p))
Ponto(x=1, y=2)
{'x': 1, 'y': 2}
O vars() mostra os atributos do objeto como um dicionário. É assim que o Python guarda os dados de cada instância.
Quando criar uma classe
Eu crio uma classe quando tenho estado e comportamento que andam juntos, como uma conta bancária, que tem saldo e sabe depositar e sacar. Se a classe só tem métodos e nenhum dado, ela provavelmente deveria ser uma função (ou um módulo). Uma Calculadora com somar(a, b) e subtrair(a, b) sem nenhum atributo é a forma de escrever Java dentro do Python.
Exercício 1
Uma conta bancária
Crie ContaBancaria com titular e saldo inicial (padrão 0), e os métodos depositar e sacar. Valores inválidos e saques acima do saldo levantam ValueError.