Type hints
Esta aula cobre type hints em Python, incluindo anotações de tipo, o módulo typing com List, Dict e Optional, os benefícios de usá-los e uma visão geral do mypy para verificação estática de tipos.
Type hints (ou anotações de tipo) são uma funcionalidade introduzida no Python 3.5 que permite indicar os tipos esperados de argumentos de funções, valores de retorno e variáveis. Embora o Python continue sendo uma linguagem dinamicamente tipada, as type hints trazem os benefícios da verificação estática de tipos, melhorando a legibilidade, a documentação e a capacidade de detecção de erros antes da execução. Nesta aula, exploraremos como usar anotações de tipo, o módulo typing para tipos mais complexos, por que adotá-las e uma introdução ao mypy para verificação de tipos.
Anotações de tipo
As anotações de tipo permitem especificar o tipo esperado de um parâmetro ou o tipo de retorno de uma função. Elas são escritas usando dois pontos (:) após o nome do parâmetro e uma seta (->) antes do tipo de retorno. Por exemplo:
def saudacao(nome: str) -> str:
return f"Olá, {nome}!"
Neste exemplo, indicamos que nome deve ser uma string e que a função retorna uma string. Essas anotações não afetam o comportamento em tempo de execução — o Python não verifica os tipos automaticamente. Elas servem principalmente para documentação e para ferramentas externas, como o mypy. Você também pode anotar variáveis:
idade: int = 30
nome: str = "Alice"
As anotações são armazenadas no dicionário __annotations__ do módulo ou função, podendo ser acessadas em tempo de execução, se necessário.
typing (List, Dict, Optional)
Para tipos mais complexos, como listas, dicionários e tipos opcionais, usamos o módulo typing. Ele fornece classes genéricas como List, Dict, Optional, Union, entre outros. Por exemplo:
from typing import List, Dict, Optional
def processar_itens(itens: List[str]) -> None:
for item in itens:
print(item)
def obter_config(chave: str) -> Optional[Dict[str, int]]:
# retorna um dicionário ou None
config = {"porta": 8080, "timeout": 30}
return config.get(chave) # retorna None se chave não existir
List[str] indica uma lista de strings; Dict[str, int] indica um dicionário com chaves string e valores inteiros; Optional[Dict[str, int]] é equivalente a Union[Dict[str, int], None], significando que o valor pode ser o dicionário ou None. Outros tipos úteis incluem Tuple, Set, Any (para qualquer tipo) e Union para múltiplos tipos possíveis.
Por que usar
Usar type hints traz diversos benefícios:
- Documentação automática: Os tipos servem como documentação viva, facilitando o entendimento do código por outros desenvolvedores (ou por você mesmo no futuro).
- Detecção precoce de erros: Ferramentas como
mypypodem encontrar bugs antes mesmo de executar o código, como passar um inteiro onde se espera uma string. - Melhor suporte em IDEs: Editores como VS Code e PyCharm usam type hints para fornecer autocompletar, inferência de tipos e detecção de erros em tempo real.
- Facilita refatoração: Com tipos claros, alterar o código fica mais seguro, pois você sabe exatamente o que cada função espera e retorna.
- Padronização: Em projetos grandes, type hints ajudam a manter consistência e reduzir ambiguidades.
Embora exijam um esforço inicial para escrever, os benefícios a longo prazo superam o custo, especialmente em projetos colaborativos ou de longa duração.
mypy (visão geral)
mypy é um verificador de tipos estático para Python. Ele analisa seu código-fonte e relata inconsistências de tipo com base nas anotações. Para instalar, use pip install mypy. Em seguida, execute mypy meu_arquivo.py para verificar o arquivo. Exemplo:
# arquivo: exemplo.py
from typing import List
def soma(numeros: List[int]) -> int:
return sum(numeros)
resultado = soma([1, 2, 3])
print(resultado)
Ao executar mypy exemplo.py, nenhum erro será reportado. Mas se você alterar a chamada para soma([1, "2", 3]), o mypy indicará um erro de tipo. O mypy suporta configurações via arquivo mypy.ini ou pyproject.toml, permitindo ajustar o rigor da verificação.
Boas práticas
- Use type hints consistentemente em todo o projeto, especialmente em funções públicas e APIs.
- Prefira tipos genéricos do módulo
typingem vez de tipos comolistoudictpara maior clareza (ex.:List[int]vslist). - Evite usar
Anya menos que seja realmente necessário, pois ele desativa a verificação de tipos. - Para valores opcionais, prefira
Optional[T]em vez deUnion[T, None]. - Execute o mypy periodicamente (por exemplo, em um hook de pré-commit) para manter a qualidade do código.
Referências
- Documentação oficial do módulo typing
- Documentação oficial do mypy
- PEP 484 – Type Hints
- Python Type Checking (Real Python)
- Optional no módulo typing
- Type Hints no VS Code
Exercícios
-
Escreva uma função anotada que receba uma lista de números inteiros e retorne a soma dos quadrados dos números pares.
✓ Resposta:from typing import List def soma_quadrados_pares(numeros: List[int]) -> int: return sum(x**2 for x in numeros if x % 2 == 0) -
Crie uma função que receba um dicionário com chaves string e valores inteiros, e retorne a soma de todos os valores. Use type hints.
✓ Resposta:from typing import Dict def soma_valores(dicionario: Dict[str, int]) -> int: return sum(dicionario.values()) -
Implemente uma função que receba um nome (string) e uma idade (int) opcional, e retorne uma saudação personalizada. Se a idade for fornecida, inclua-a na mensagem.
✓ Resposta:from typing import Optional def saudacao(nome: str, idade: Optional[int] = None) -> str: if idade is not None: return f"Olá, {nome}! Você tem {idade} anos." return f"Olá, {nome}!" -
Escreva uma função que receba uma lista de strings e retorne uma lista com as strings que têm mais de 5 caracteres. Use type hints.
✓ Resposta:from typing import List def strings_longas(lista: List[str]) -> List[str]: return [s for s in lista if len(s) > 5] -
Explique em uma frase o que o mypy faz e como executá-lo em um arquivo chamado
app.py.✓ Resposta:O mypy é um verificador de tipos estático para Python que analisa o código-fonte em busca de inconsistências de tipo com base nas anotações; para executá-lo no arquivo
app.py, use o comandomypy app.pyno terminal.