Python Type Hints: Código Mais Seguro e Claro
Você provavelmente já encontrou uma função Python que retorna tipos diferentes dependendo da entrada, ou uma variável que muda de tipo no meio do caminho. Essas ambiguidades levam a erros em tempo de execução que poderiam ter sido detectados antes. Python type hints resolvem isso permitindo que você anote os tipos esperados, tornando seu código autodocumentado e permitindo que ferramentas de análise estática detectem erros antes da execução.
Neste artigo, vamos explorar como usar type hints em Python de forma eficaz, desde anotações básicas até padrões avançados, e como eles contribuem para um código mais seguro e claro.
O que são Python Type Hints?
Type hints (também chamados de anotações de tipo) são uma sintaxe introduzida no Python 3.5 (PEP 484) que permite especificar os tipos esperados de variáveis, parâmetros de função e valores de retorno. Eles não são aplicados em tempo de execução, mas são usados por verificadores estáticos de tipo como mypy, pyright e IDEs para detectar erros relacionados a tipos.
Por exemplo:
def greet(name: str) -> str:
return f"Hello, {name}"
Aqui, name: str indica que name deve ser uma string, e -> str indica que a função retorna uma string.
Por que usar Type Hints?
- Detecção precoce de bugs: Verificadores estáticos de tipo podem detectar incompatibilidades de tipo antes de você executar o código.
- Legibilidade aprimorada: Type hints servem como documentação inline, tornando mais fácil para outros (e para você no futuro) entender o código.
- Melhor suporte de IDE: Autocompletar, refatoração e navegação tornam-se mais precisos.
- Manutenibilidade aprimorada: Ao refatorar, type hints ajudam a garantir que você não quebre contratos.
- Facilita a colaboração: Equipes podem comunicar interfaces esperadas de forma clara.
Anotações de Tipo Básicas
Você pode anotar variáveis, parâmetros de função e tipos de retorno.
Variáveis
age: int = 30
name: str = "Alice"
Funções
def add(a: int, b: int) -> int:
return a + b
Coleções
Para listas, dicionários, etc., use o módulo typing (ou genéricos embutidos no Python 3.9+):
from typing import List, Dict
def process(items: List[str]) -> Dict[str, int]:
return {item: len(item) for item in items}
No Python 3.9+, você pode usar list[str] e dict[str, int] diretamente.
Type Hints Avançados
À medida que seu código cresce, você encontrará cenários mais complexos. Aqui estão alguns recursos avançados.
Optional e Union
Optional[T] é uma abreviação para Union[T, None], indicando um valor que pode ser do tipo T ou None.
from typing import Optional
def find_user(user_id: int) -> Optional[str]:
# returns username or None if not found
...
No Python 3.10+, você pode usar o operador |: str | None.
Callable
Para funções como argumentos:
from typing import Callable
def apply_func(func: Callable[[int], int], value: int) -> int:
return func(value)
Genéricos
Crie componentes reutilizáveis com variáveis de tipo:
from typing import TypeVar, List
T = TypeVar('T')
def first(items: List[T]) -> T:
return items[0]
TypedDict
Para dicionários com um conjunto fixo de chaves e tipos de valores:
from typing import TypedDict
class User(TypedDict):
name: str
age: int
def greet(user: User) -> str:
return f"Hello, {user['name']}"
Usando Verificadores Estáticos de Tipo
Type hints só são úteis se você os verificar. Ferramentas populares incluem mypy, pyright e pyre. Vamos ver como usar o mypy.
- Instale o mypy:
pip install mypy - Execute-o no seu código:
mypy your_script.py - Corrija os erros relatados.
Por exemplo, dado:
def add(a: int, b: int) -> int:
return a + b
add("1", "2")
mypy irá reportar: error: Argument 1 to "add" has incompatible type "str"; expected "int".
Você pode configurar o mypy através de um arquivo mypy.ini ou pyproject.toml para aplicar verificações mais rigorosas.
Boas Práticas para Type Hints
- Seja consistente: Anote todas as funções e métodos públicos.
- Use
Anycom moderação: Ele desativa a verificação de tipo para aquele valor. - Prefira tipos concretos em vez de
Anyouobject. - Use
Optionalpara valores que podem ser None. - Aproveite
Protocolpara subtipagem estrutural (duck typing com segurança de tipos). - Mantenha os type hints atualizados ao refatorar.
- Execute um verificador de tipos no CI para detectar problemas cedo.
Armadilhas Comuns e Como Evitá-las
- Ignorar erros de tipo: Não apenas silencie o mypy; entenda e corrija o problema.
- Usar
Anyem excesso: Isso anula o propósito dos type hints. - Esquecer de anotar tipos de retorno: Especialmente para funções que retornam None.
- Usar argumentos padrão mutáveis com type hints: Isso é uma armadilha separada do Python, mas type hints não irão capturá-la.
- Não atualizar os hints após mudanças: Leva a uma falsa confiança.
Type Hints na Prática: Um Pequeno Exemplo
Considere uma função que processa uma lista de números e retorna a média. Sem type hints, não está claro quais tipos são esperados.
def average(numbers):
return sum(numbers) / len(numbers)
Com type hints:
from typing import List
def average(numbers: List[float]) -> float:
return sum(numbers) / len(numbers)
Agora, se alguém passar uma lista de strings, o mypy irá sinalizar.
Integrando Type Hints ao Seu Fluxo de Trabalho
Para aproveitar ao máximo os type hints, integre-os ao seu processo de desenvolvimento:
- Adicione type hints gradualmente a bases de código existentes.
- Configure sua IDE para mostrar erros de tipo.
- Adicione uma etapa de verificação de tipos ao seu pipeline de CI.
- Use hooks de pré-commit para executar o mypy antes dos commits.
Por exemplo, uma etapa simples de workflow do GitHub Actions:
- name: Type check
run: mypy .
FAQ
Type hints afetam o desempenho em tempo de execução?
Não, type hints são ignorados em tempo de execução. Eles são armazenados em __annotations__, mas não impactam a velocidade de execução.
Posso usar type hints em versões mais antigas do Python?
Type hints foram introduzidos no Python 3.5. Para versões mais antigas, você pode usar anotações baseadas em comentários (por exemplo, # type: int), mas é recomendado atualizar para uma versão do Python suportada.
Qual é a diferença entre List e list em type hints?
List de typing é usado no Python 3.5-3.8. No Python 3.9+, você pode usar o list embutido diretamente. Ambos são equivalentes para verificação de tipos.
Pronto para melhorar a qualidade do seu código? Comece adicionando type hints a uma função hoje e execute o mypy para ver os benefícios. Para mais ferramentas de desenvolvedor, confira nosso JSON Formatter para formatar e validar seus dados JSON sem esforço.