Menu

Type hints em Python: anotações para funções, listas, dicionários e mais

O que são type hints em Python, quando ajudam e a sintaxe para anotar variáveis, assinaturas de função, containers e valores opcionais.

Anotações que descrevem, não impõem

Um type hint é uma nota que você prende a um nome — geralmente um parâmetro de função — dizendo "isto deveria ser um int", "isto retorna uma lista de strings", e assim por diante. O Python não checa em tempo de execução. Passar uma string onde você anotou int não dispara erro. Seu editor e ferramentas externas (mypy, pyright, Pyright via Pylance do VS Code) leem as anotações e te avisam antes do código rodar.

O caso mais simples possível:

main.py
Output
Click Run to see the output here.

name: str anota o parâmetro. -> str anota o valor de retorno. As duas chamadas rodam. A segunda está errada — um type checker estático apontaria — mas o próprio Python processa alegremente porque 42 por acaso suporta interpolação f"{...}".

Esse é o modelo mental crucial: hints são documentação que uma máquina consegue ler. Não mudam o runtime.

Por que incomodar?

Três ganhos concretos, em ordem de quão rápido se pagam:

  1. Seu editor fica mais esperto. Autocomplete mostra os métodos certos, renomeações propagam corretamente e passar o mouse numa variável te diz o tipo.
  2. Assinaturas de função ficam autoexplicativas. def fetch(url: str, timeout: float = 5.0) -> dict: diz a um leitor exatamente o que passar e o que vai voltar — sem precisar ler o corpo.
  3. Type checkers pegam erros antes de rodar. Rodar mypy . num projeto traz à tona o tipo de bug que testes unitários muitas vezes perdem — None retornado onde você esperava um valor, um dict usado onde pertence uma lista.

Para um script de um arquivo que é só você e só para hoje, pule as anotações. Para qualquer coisa à qual você vai voltar ou compartilhar, os quinze segundos que elas levam para escrever se pagam em uma hora.

Tipos embutidos básicos

Você não precisa de import para nenhum desses:

main.py
Output
Click Run to see the output here.

Anotações de variável (name: str = "Rosa") raramente são necessárias — o Python infere o tipo pelo lado direito. Guarde para parâmetros, tipos de retorno e o caso ocasional em que o tipo inferido é ambíguo.

Funções que não retornam nada usam -> None:

main.py
Output
Click Run to see the output here.

Listas, dicts, tuplas e sets

Containers precisam de mais uma informação — o que contêm. O Python moderno permite indexar os tipos embutidos diretamente:

main.py
Output
Click Run to see the output here.

Lendo em voz alta:

  • list[float] — uma lista de floats.
  • dict[str, int] — um dict com chaves string e valores int.
  • tuple[float, float] — uma tupla de exatamente dois floats.
  • set[str] — um set de strings.

A sintaxe de subscrição list[...], dict[...] funciona no Python 3.9 e posterior. Em código mais antigo você vai ver List, Dict, Tuple importados de typing — mesmo significado, ortografia antiga.

Valores opcionais

"Pode ser None" é comum. Tem duas ortografias equivalentes — as duas estão bem, mas a mais nova lê melhor:

main.py
Output
Click Run to see the output here.

str | None significa "uma string, ou None". A sintaxe | funciona no Python 3.10+. Em código mais antigo você vai ver Optional[str] do módulo typing, que significa a mesma coisa.

Quem chama e vê -> str | None sabe que precisa checar por None antes de usar o resultado — esse é o ponto todo da anotação.

Union types: isso ou aquilo

Quando um valor pode ser um de vários tipos, use |:

main.py
Output
Click Run to see the output here.

Você pode unir mais de dois tipos. int | str | float significa "qualquer um desses três".

Anotando variáveis dentro de funções

Na maior parte do tempo, o Python consegue descobrir o tipo de uma variável local pelo inicializador. Você só precisa de uma anotação quando:

main.py
Output
Click Run to see the output here.
  • O container começa vazio e o type checker não consegue adivinhar o conteúdo.
  • O valor poderia ser de vários tipos e você quer se comprometer com um.
  • Você quer documentar a intenção para um leitor humano.

typing.Any é a válvula de escape — "não quero anotar isso com precisão". Use com parcimônia. Abusar de Any torna o resto das suas type hints inúteis.

Anotando classes

Atributos de classe e assinaturas de método anotam da mesma forma que qualquer outra função:

main.py
Output
Click Run to see the output here.

Dataclasses na verdade exigem anotações de tipo — o decorador @dataclass lê para gerar __init__ e __repr__. Esse é o único lugar em que anotações afetam o comportamento em runtime.

Tuplas e o caso "qualquer tamanho"

tuple[...] tem dois formatos que confundem iniciantes:

main.py
Output
Click Run to see the output here.
  • tuple[float, float] — exatamente dois floats.
  • tuple[int, ...] — qualquer número de ints. O ... (um elemento sintático real no sistema de tipos) significa "e assim por diante".

Callables e aliases de tipo

Quando uma função recebe ou retorna outra função, use Callable:

main.py
Output
Click Run to see the output here.

Callable[[int], int] significa "uma função que recebe um int e retorna um int".

Quando uma anotação fica repetitiva, dê um nome:

main.py
Output
Click Run to see the output here.

Um alias é só uma atribuição Python comum. Em qualquer lugar em que você usaria a forma longa, o nome curto funciona.

Rodando um type checker

O interpretador Python ignora as type hints. Para de fato checar, instale um type checker. mypy é o original; pyright (usado pelo Pylance do VS Code) é mais rápido.

pip install mypy
mypy seu_projeto/

A primeira execução vai revelar erros em lugares que você não tinha notado. Trabalhe neles incrementalmente — # type: ignore silencia uma linha quando você precisa seguir em frente.

IDEs modernos rodam type checking continuamente enquanto você edita, então a maioria do feedback chega antes de você salvar.

Quando type hints não encaixam

  • Scripts exploratórios rápidos. Anotações adicionam atrito a código que vive por uma hora.
  • Código muito dinâmico. Metaprogramação, sistemas de plugin e padrões parecidos muitas vezes ultrapassam o que o sistema de tipos consegue descrever. Anote a API externa e deixe o miolo solto.
  • Bibliotecas de terceiros sem tipos. Se uma biblioteca que você importa não tem info de tipo, Any vaza para seu código. Tudo bem — não é seu código para anotar.

Para tudo no meio, type hints são um hábito pequeno com grande retorno. O custo é algumas teclas a mais por assinatura de função. O retorno é menos bugs, refactors mais fáceis e código que se documenta.

Próxima: módulos e imports

Agora você tem toda a ferramenta em nível de função — argumentos, decoradores, type hints. A seguir vamos olhar como o Python organiza código entre arquivos: módulos, pacotes e o sistema de import.

Perguntas frequentes

O que são type hints em Python?

Type hints são anotações que descrevem os tipos esperados de variáveis, parâmetros de função e valores de retorno. O próprio Python não aplica em tempo de execução — são para ferramentas (IDEs, linters, type checkers como mypy ou pyright) e para humanos lendo o código.

Type hints deixam o Python mais rápido?

Não. O interpretador Python ignora type hints em tempo de execução. O ganho é no seu loop de desenvolvimento — menos typos pegos pelos editores, assinaturas de função mais claras, refactors mais seguros.

Quando devo adicionar type hints?

Adicione em assinaturas públicas de função — parâmetros e tipos de retorno. Adicione com parcimônia dentro do corpo das funções, só onde o tipo de uma variável não é óbvio. Para scripts de uma vez, são opcionais. Para código compartilhado e bibliotecas, se pagam rápido.

Aprenda a programar com o Coddy

COMEÇAR