Definindo tipos de variáveis e de listas. (Python, TypeHinting)

Definindo tipos de variáveis e de listas. (Python, TypeHinting)

Overview

Bem-vindos ao mundo das dicas de tipo em Python! Nesse post aconchegante e informativo, vamos mergulhar nas maravilhas das anotações de tipo, introduzidas pela PEP 484. Se você sempre quis entender como tornar seu código mais claro e menos propenso a erros sem perder a flexibilidade do Python, este guia é para você. Vamos descomplicar a tipagem em Python com exemplos fáceis de seguir e descobrir por que isso pode ser um grande aliado no seu desenvolvimento. Pegue seu café e prepare-se para uma exploração tipográfica!

Fazer isso é bem simples e deixa seu código mais inteligível.

Contexto

Desde maio de 2015, definir tipos para as variáveis foi incluído no PEP (PEP0484: Type Hints) e implementado neste repositorio. A ideia desta atualização foi facilitar a analise do código, os processos de refatoração e possibilitar validações que só seriam possíveis durante a execução. (Quem diria que definir tipos para as variáveis seria tão útil, certo? 😉)

Isso quer dizer que o Python está virando uma linguagem "fortemente tipada"? Não. Como o próprio nome da diretiva do PEP sugere, esta definição é uma hint, ou seja, uma dica. Se você quiser ignorar o tipo sugerido, está liberado. (mas pq vc faria isso?)

O processo é bem simples e pode ser utilizado com toda a flexibilidade do Python. Vamos aos exemplos…

Definindo tipo de uma variável

1foo: int = 42
2bar: str = "bacon"

O código acima cria as variáveis foo, com o tipo sugerido de int e bar do tipo string (str). Caso você tente associar o valor "x" na variável foo (que foi definida como int),você vai conseguir e esta variável vai passar a ser considerada como uma string, que é o comportamento normal do Python.

A vantagem deste processo está na sua IDE. Se ela for (pelo menos) razoável, ela vai te avisar que o valor esperado para a variável foo é alguma coisa do tipo int e isso vai te ajudar a evitar bugs durante o desenvolvimento.

Você pode utilizar qualquer tipo como hint da sua variável e caso precise definir dois (ou mais) tipos possíveis para uma variável, utilize o Union (do pacote typing):

1from typing impoort Union
2
3foobar: Union[int, str] = "bar"

Desta forma, se você atribuir int ou str, a IDE não vai emitir um warning/erro.

Definindo tipo dos itens de uma lista

Seguindo a lógica do exemplo acima, voce poderia definir uma variável como list, mas isso não vai te falar do que é esta lista.

Todavia, isso é possível. Basta importar List do pacote typing.

1from typing import List
2
3foo: List[int] = [1,2,3,4]
4bar: List[str] = ["x", "y"]

No exemplo acima, a variável foo agora é uma lista de int e a bar é uma lista de strings. Você pode utilizar o Union também para falar que a lista pode ser mista.

Exemplo

Segue um exemplo mais completo deste tipo de tipagem

 1# -*- coding: utf-8 -*-
 2from datetime import datetime
 3from typing import List, Union
 4
 5
 6class Bar:
 7    _id: int
 8    description: str
 9
10class Foo:
11    def __init__(self, _id: int, name: str, bars: List[Bar],
12                 correlation_ids: List[str], created_at: Union[datetime, None] = None,
13                 misc: Union[List[int], List[str]] = None):
14        self._id: int = _id
15        self.name: str = name
16        self.created_at: Union[datetime, None] =  datetime.utcnow() if created_at is None else created_at
17        self.bars: List[Bar] = bars
18        self.correlation_ids: List[str] = correlation_ids
19        self.misc: Union[List[int], List[str]] = misc
20
21if __name__ == '__main__':
22    f = Foo(_id=1,
23            name="Foo1",
24            bars=[Bar(), Bar(), Bar()],
25            correlation_ids=["1", "2", "3"],
26            created_at=datetime.now(),
27            misc=[1, "x"])

Espero ter ajudado.