Recursos avançados de Python
(blog.edward-li.com)- 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,protocolsecontext 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-elseewalrus - 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
@overloadpermite 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
idouusername Literalpode 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 annotationspermite adiar o momento da avaliação- Mas, como funciona com tratamento em formato de string, é preciso cuidado ao usar tipos em runtime
- A
PEP 649propõ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 comoclass 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 comisinstance
# Context manager
- Objetos com métodos
__enter__e__exit__são usados em blocoswith - O decorador
contextlib.contextmanagerpermite 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-casepermite 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 sembreak - 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 < 10deixam 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_cachee@cachearmazenam resultados de funções para melhorar o desempenho- São úteis em funções recursivas ou com muitos cálculos repetidos
@cachefoi 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 comawait- 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