- Apresenta 14 recursos avançados pouco conhecidos do Python com exemplos práticos
- Oferece uma explicação aprofundada sobre tipagem estática e design estrutural, incluindo
typing, generics, protocols e context managers
- Também inclui pattern matching estrutural introduzido no Python 3.10+ e técnicas de otimização de desempenho como slots e metaclasses
- Reúne dicas para escrever código mais limpo, como
f-string, cache, future, proxy, for-else e walrus
- Fornece links e materiais de referência para estudo adicional em cada recurso, com uma estrutura acessível até para desenvolvedores juniores
Resumo de 14 recursos avançados do Python
# Sobrecarga de tipagem
- O decorador
@overload permite definir múltiplas assinaturas de tipo para uma única função
- O verificador de tipos consegue inferir com precisão o tipo de retorno de acordo com os argumentos passados
- Também é possível restringir valores de string usando
Literal
- Também dá para implementar assinaturas de função que exigem apenas um entre
id ou username
Literal pode ser usado como uma alternativa leve a enums para maior segurança de tipos
# Argumentos somente por palavra-chave / somente posicionais
- Com
*, é possível definir argumentos somente por palavra-chave (não podem ser usados como posicionais)
- Com
/, é possível definir argumentos somente posicionais (não podem ser usados como palavra-chave)
- Isso permite forçar com clareza a forma de uso dos argumentos no design de APIs
# Anotações futuras (__future__)
- Como type hints normalmente são avaliadas imediatamente em tempo de execução, podem surgir problemas com a ordem das declarações
from __future__ import annotations permite adiar o momento da avaliação
- Mas, como funciona com tratamento em formato de string, é preciso cuidado ao usar tipos em runtime
- A
PEP 649 propõe uma melhoria com avaliação tardia no atributo __annotations__
# Sintaxe de genéricos (Generic)
- A partir do Python 3.12, há suporte à nova sintaxe de definição de tipos genéricos
- Em vez de
TypeVar, é possível usar formas mais intuitivas como class Foo[T, U: int]
- Generics variádicos (Variadic Generics) também foram introduzidos para lidar com vários tipos
- A definição de aliases de tipo também ficou mais simples, como em
type Vector = list[float]
# Protocolos (Protocols)
- Permitem implementar subtipagem estrutural como uma versão de verificação de tipos do Duck Typing
- Se uma classe tiver determinados métodos, ela pode ser compatível com o tipo mesmo sem herdar dele
- Com
@runtime_checkable, isso também pode ser estendido para verificações com isinstance
# Context manager
- Objetos com métodos
__enter__ e __exit__ são usados em blocos with
- O decorador
contextlib.contextmanager permite uma implementação simples baseada em função
- As tarefas de configuração e limpeza são executadas antes e depois do
yield
# Pattern matching estrutural
- A sintaxe
match-case permite tratar desvios em estruturas de dados complexas de forma intuitiva
- Suporta destructuring de tuplas/listas, padrão OR, condições de guarda (
if) e curingas
- Como o desvio pode ser feito com base na estrutura dos dados, há ganho de legibilidade e manutenção
# Otimização com __slots__
- Usa slots fixos no lugar de
__dict__, otimizando memória e velocidade
__slots__ usa uma tupla com apenas os nomes dos atributos
- Também evita a adição de atributos desnecessários à classe
- Ainda assim, é uma micro-otimização e deve ser usada com cautela
# Coletânea de dicas de estilo de código Python
- Sintaxe for-else: o
else é executado quando o loop termina sem break
- Operador walrus (
:=): permite declarar e testar uma variável ao mesmo tempo
- Curto-circuito com
or: retorna o primeiro valor verdadeiro entre vários
- Encadeamento de operadores de comparação: expressões como
0 < x < 10 deixam o código mais conciso
# Formatação avançada com f-string
- A sintaxe
f"{variável=}" permite representações úteis para depuração
- Várias opções como formatação numérica (
:.2f, :+.2f, :,) e de data (%Y-%m-%d)
- Também aproveita a mini linguagem de formatação para alinhamento central, padding e porcentagem
# Decoradores de cache
@lru_cache e @cache armazenam resultados de funções para melhorar o desempenho
- São úteis em funções recursivas ou com muitos cálculos repetidos
@cache foi introduzido no Python 3.9 e fornece cache ilimitado por padrão
# Future no Python
- Oferece um mecanismo de objeto assíncrono semelhante ao Promise do JS
- Permite gerenciar resultados de forma assíncrona com
Future.set_result(), add_done_callback() etc.
asyncio.Future() pode ser usado junto com await
- Em conjunto com
ThreadPoolExecutor, também permite processamento paralelo em segundo plano
# Propriedade proxy (Proxy Property)
- Faz com que um atributo de classe funcione tanto como propriedade quanto como função
- Com
__get__, __call__ e __repr__, é possível oferecer essas duas formas de uso
- No design de API, isso pode permitir tratar valores padrão e chamadas com parâmetros em uma única interface
- Vale mais como referência experimental do que como exemplo de uso prático
# Metaclasses
- São a classe das classes, responsáveis por criar a própria classe
- Permitem lógica meta, como manipulação de atributos da classe ou registro automático
- Na prática, na maioria dos casos podem ser substituídas por decoradores
- Frameworks como Django, SQLAlchemy e Pydantic usam metaclasses internamente
5 comentários
Do ponto de vista de backend, já tive a experiência de que metaclasses tornam a depuração mais difícil.
Vale lembrar que
for-elsemuitas vezes é considerado um antipadrão, por haver opiniões de que não oferece boa legibilidade nem clareza, e queasyncio.Futureé tratado como um detalhe interno de implementação doasyncio.Obrigado. Vou aplicar especialmente a nº 10 imediatamente.
Adicionar regras de codificação com IA..
Obrigado pela dica valiosa.
Comentários no Hacker News
Olá! Sou o autor original do blog! Fiquei surpreso ao ver meu texto na primeira página do HN às 4 da manhã
Sempre que uso Python, fico preocupado se o código vai parecer que está usando Python do jeito errado
Python deve continuar sendo Python, e golang, Rust e Typescript devem manter cada um sua própria filosofia e design
A maior vantagem do Python é parecer um pseudocódigo executável
Observação sobre a avaliação do parágrafo 9.3: se houver uma string vazia, a avaliação acontece de forma diferente
Como alguém que migrou de Javascript/Typescript para Python, isso foi um recurso útil
A maioria dos recursos não é avançada
O que eu mudaria na lista é a inclusão de contêineres de collections.abc
Foi prazeroso ler este texto