Uma classe empacota dados e o que fazer com eles
Uma classe permite definir um tipo de coisa — um usuário, uma conta bancária, uma configuração, uma requisição — e tudo que essa coisa deveria poder fazer. A coisa é uma instância da classe. As ações se chamam métodos.
Aqui vai a classe mais simples possível:
Dissecando:
class User:começa uma definição de classe. Nomes de classe usam PascalCase por convenção.__init__é o inicializador. Roda automaticamente quando você cria uma instância nova. Configura os atributos da instância usandoself.algo = ....greeté um método.selfé como um método se refere à instância sobre a qual foi chamado.User("Rosa", "rosa@example.com")cria uma instância. O Python chama__init__comselfsetado para a instância nova e os outros argumentos repassados.user.greet()chama o método. O Python passausercomoselfautomaticamente.
self é só o primeiro argumento
self não é palavra-chave. É o nome que o Python dá ao primeiro parâmetro de métodos de instância — a instância sobre a qual o método está rodando. Você poderia chamar de qualquer coisa; todo mundo usa self porque todo mundo usa.
Todo método de instância recebe self como primeiro parâmetro. É assim que um método sabe de qual instância ler ou mudar.
Adicionando comportamento
Métodos podem ler e alterar estado:
__repr__ é outro método especial — um gancho para "como eu apareço quando impresso?". Definir um bom paga dividendos durante debug.
Atributos de classe vs atributos de instância
Atributos definidos no corpo da classe (fora do __init__) são compartilhados entre todas as instâncias. Atributos atribuídos a self são por instância:
Use atributos de classe para valores genuinamente compartilhados — constantes, contadores, config. Coloque dados específicos de instância no __init__.
Herança
Uma classe pode herdar de outra, ganhando os métodos e atributos de graça e adicionando ou sobrescrevendo conforme necessário:
super() te dá acesso à classe pai — comumente usado dentro do __init__ para inicializar os atributos do pai antes de adicionar os seus:
Herança é útil mas fácil de abusar. Um programador Python novo muitas vezes apela à herança quando composição — segurar um objeto como atributo — seria mais claro. Comece com uma estrutura de classes plana e só introduza herança quando tiver uma relação "é um" de verdade.
Dataclasses: um default mais amigável para registros
Quando você só quer que uma classe guarde alguns atributos com algum comportamento de igualdade e representação, @dataclass poupa muito boilerplate:
Compare com escrever __init__, __repr__ e __eq__ na mão. Dataclasses são a primeira escolha certa quando você escreveria class Thing com nada além de __init__ setando atributos.
Properties: atributos computados
Às vezes você quer um "atributo" que na verdade é computado. @property faz parecer acesso de atributo:
Use properties quando escreveria obj.get_something() — substituir por uma property torna a API mais natural. Não use para esconder operações caras; um usuário espera que acesso a atributo seja rápido.
Privado por convenção
O Python não tem privado de verdade. Por convenção, atributos com underscore no começo são intencionalmente privados — espera-se que leitores não toquem de fora da classe:
class Cache:
def __init__(self):
self._store = {}
def put(self, key, value):
self._store[key] = value
def get(self, key, default=None):
return self._store.get(key, default)
Nomes com underscore duplo (__name) disparam name mangling, que adiciona o nome da classe ao atributo. Isso é ferramenta para evitar colisões em herança, não medida de segurança.
Quando não usar uma classe
Se tudo que você tem é um pacote de dados relacionados, uma dataclass, um dict simples ou uma named tuple serve. Se tudo que você tem é uma função, ela não precisa de classe para segurar. Recorra a classes quando você tem ambos estado e comportamento amarrados — especialmente quando vai ter várias instâncias do mesmo tipo.
Um exemplo final
Um pequeno buffer de log estilo arquivo:
Repare __len__ — outro método mágico. Defini-lo faz len(logger) funcionar, porque len(x) é de fato uma chamada para x.__len__(). O Python tem dezenas desses ganchos; você pega conforme precisa.
Próxima: geradores
Classes amarram dados e comportamento. O próximo capítulo olha para um tipo diferente de abstração — iteração — começando por geradores: funções que produzem valores um de cada vez, pausando entre eles. Combinam lindamente com a instrução with / context managers que você conhece logo depois.
Perguntas frequentes
O que é uma classe em Python?
Uma classe é um molde para criar objetos que agrupam dados (atributos) e comportamento (métodos). class User: define uma classe User; User(...) cria uma instância. Classes são a principal ferramenta do Python para modelar coisas que têm tanto estado quanto comportamento.
O que significa self em Python?
self é o primeiro parâmetro de todo método de instância. Quando você chama user.greet(), o Python passa a instância user como self. Dentro do método, self.name acessa o atributo name daquele usuário. O nome self é convenção, não palavra-chave — mas todo pythonista usa.
Python é orientado a objetos?
Sim — tudo em Python é objeto, inclusive números, strings e funções. Você pode fazer programação orientada a objetos quando encaixa, mas o Python não força. Muitos programas Python do mundo real usam classes com parcimônia, preferindo funções simples e estruturas de dados quando possível.