Métodos de Classe vs. Instância vs. Estáticos
Python oferece três tipos de métodos. Métodos de instância operam em objetos, métodos de classe na classe (frequentemente fábricas) e métodos estáticos como funções com namespace sem self ou cls implícitos.
Receita
class User:
def __init__(self, email: str) -> None:
self.email = email
def domain(self) -> str:
return self.email.split("@", 1)[1]
@classmethod
def from_row(cls, row: dict[str, str]) -> "User":
return cls(row["email"])
@staticmethod
def is_valid_email(email: str) -> bool:
return "@" in email and "." in email.split("@", 1)[-1]Quando usar isso:
- Construtores alternativos (
from_json,from_env) - Utilitários logicamente agrupados com a classe, mas que não precisam de estado
- Métodos de fábrica herdados que respeitam o
clsda subclasse - Métodos de classe de enumeração/personalizados que modificam o estado da classe
Exemplo de Trabalho
from datetime import datetime, timezone
class Event:
def __init__(self, name: str, ts: datetime) -> None:
self.name = name
self.ts = ts
def age_seconds(self, now: datetime | None = None) -> float:
now = now or datetime.now(timezone.utc)
return (now - self.ts).total_seconds()
@classmethod
def now(cls, name: str) -> "Event":
return cls(name, datetime.now(timezone.utc))
@classmethod
def from_iso(cls, name: str, iso: str) -> "Event":
ts = datetime.fromisoformat(iso.replace("Z", "+00:00"))
return cls(name, ts)
@staticmethod
def normalize_name(name: str) -> str:
return name.strip().lower()
class AdminEvent(Event):
pass
if __name__ == "__main__":
base = Event.now("deploy")
admin = AdminEvent.now("promote")
print(type(base), type(admin))
print(Event.is_valid_email("a@b.com"))O que isso demonstra:
- O método de classe
nowé um construtor alternativo AdminEvent.nowretornaAdminEventporqueclsé uma subclasse- O método de instância
age_secondsusa o estado do objeto - O método estático
normalize_namenão precisa deselfnem decls
Mergulho Profundo
Como Funciona
- Métodos vinculados - Métodos de instância vinculam
selfno momento da chamada. - Descritor de método de classe - Passa a classe como primeiro argumento automaticamente.
- Descritor de método estático - Nenhum argumento automático.
- Herança -
clsem um método de classe é a classe real chamada (AdminEventem vez deEvent). - Acesso - Métodos de classe podem acessar atributos de classe; métodos de instância, atributos de instância.
Quando Usar Cada Um
| Decorator | 1º arg | Uso Típico |
|---|---|---|
| (nenhum) | self | Comportamento do objeto |
@classmethod | cls | Fábricas, configuração de classe |
@staticmethod | nenhum | Auxiliar agrupado |
Notas do Python
# Padrão de método de classe estilo enum
class Money:
def __init__(self, amount: int, currency: str) -> None:
self.amount = amount
self.currency = currency
@classmethod
def usd(cls, amount: int) -> "Money":
return cls(amount, "USD")Armadilhas
staticmethodquandoclassmethodé necessário - Fábrica que retornaclsfalha em subclasses comstaticmethod. Correção: Useclassmethodpara construtores polimórficos.classmethodacessando estado da instância -selfnão está disponível. Correção: Passe a instância explicitamente ou use um método de instância.- Confusão com função em nível de módulo -
staticmethodque nunca toca na classe - poderia ser uma função de módulo. Correção: Usestaticmethodapenas ao agrupar a API no namespace da classe. - Ordem de
classmethodabstrato - Empilhe@classmethode@abstractmethodde acordo com a documentação da versão do Python. - Chamando
classmethodem uma instância - Permitido, mas incomum - ainda passa a classe real.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Função de módulo | Nenhum agrupamento de classe necessário | A API pertence à classe |
Apenas __init__ | Caminho de construção único | Múltiplas fontes de análise |
model_validate do Pydantic | Análise de DTO validada | Domínio não-Pydantic |
__post_init__ do dataclass | Validação pós-construção | Construtores alternativos |
FAQs
classmethod vs __init__?
Use fábricas de classmethod quando múltiplos caminhos de construção analisam diferentes entradas no mesmo tipo.
Por que AdminEvent.now retorna AdminEvent?
cls está vinculado à classe usada na chamada - comportamento de fábrica polimórfico.
staticmethod em instância?
Chamável a partir de uma instância, mas a ignora - sem acesso ao estado.
classmethod para decoradores?
Raro - alguns padrões de registro registram subclasses via __init_subclass__ em vez disso.
typing classmethod?
Retorne Self (3.11+) de métodos de classe para tipagem correta de subclasses.
propriedade classmethod?
Padrões de encapsulamento de propriedade classmethod a partir do Python 3.9+ existem para metaprogramação - avançado.
herança staticmethod?
Herdado inalterado - ainda sem vinculação de cls na subclasse, a menos que substituído.
nomeação de construtor alternativo?
Convenções from_json, from_env, parse - não sobrecargas de __init__.
classmethod modificando estado da classe?
Possível via padrões cls._registry - documente a segurança de thread se o estado da classe mutável for compartilhado.
fábricas de dependência fastapi?
Frequentemente funções simples - classmethods quando a fábrica está vinculada à configuração da classe de serviço.
Relacionado
- Propriedades e Descritores - descritores de método
- dataclasses - padrões de construção
- Herança e MRO -
clsno contexto MRO - Enums - métodos de classe de enumeração
Versões do Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.