Resumo: neste tutorial, você aprenderá sobre as dicas de tipo do python e como usar a ferramenta mypy para verificar os tipos estaticamente.
Introdução às dicas de tipo do Python
Algumas linguagens de programação têm tipagem estática, como C/C++. Isso significa que você precisa declarar tipos de variáveis, parâmetros e valores de retorno de uma função antecipadamente. Os tipos predefinidos permitem que os compiladores verifiquem o código antes de compilar e executar o programa.
Python usa tipagem dinâmica, na qual variáveis, parâmetros e valores de retorno de uma função podem ser de qualquer tipo. Além disso, os tipos de variáveis podem mudar durante a execução do programa.
Geralmente, a digitação dinâmica facilita a programação e causa erros inesperados que você só pode descobrir até que o programa seja executado.
As dicas de tipo do Python fornecem digitação estática opcional para aproveitar o melhor da digitação estática e dinâmica.
O exemplo a seguir define uma função simples que aceita uma string e retorna outra string:
def say_hi(name):
return f'Hi {name}'
greeting = say_hi('John')
print(greeting)
Aqui está a sintaxe para adicionar dicas de tipo a um parâmetro e valor de retorno de uma função:
parameter: type
-> type
Por exemplo, o seguinte mostra como usar dicas de tipo para o parâmetro name
e o valor de retorno da função say_hi()
:
def say_hi(name: str) -> str:
return f'Hi {name}'
greeting = say_hi('John')
print(greeting)
Saída:
Hi John
Nesta nova sintaxe, o parâmetro name
tem o tipo str
:
name: str
E o valor de retorno da função say_hi()
também tem o tipo str
:
-> str
Além do tipo str
, você pode usar outros tipos integrados, como int
, float
, bool
e bytes
para dicas de tipo.
É importante observar que o interpretador Python ignora completamente as dicas de tipo. Se você passar um número para a função say_hi()
, o programa será executado sem nenhum aviso ou erro:
def say_hi(name: str) -> str:
return f'Hi {name}'
greeting = say_hi(123)
print(greeting)
Saída:
Hi 123
Para verificar a sintaxe das dicas de tipo, você precisa usar uma ferramenta de verificação de tipo estático.
Usando uma ferramenta de verificação de tipo estático: mypy
O Python não possui uma ferramenta oficial de verificação de tipo estático. No momento, a ferramenta de terceiros mais popular é o Mypy. Como o Mypy é um pacote de terceiros, você precisa instalá-lo usando o seguinte comando pip
:
pip instal mypy
Depois de instalado mypy
, você pode usá-lo para verificar o tipo antes de executar o programa usando o seguinte comando:
mypy app.py
Mostrará a seguinte mensagem:
app.py:5: error: Argument 1 to "say_hi" has incompatible type "int"; expected "str"
Found 1 error in 1 file (checked 1 source file)
O erro indica que o argumento de say_hi
é int
enquanto o tipo esperado é str
.
Se você alterar o argumento de volta para uma string e executar mypy
novamente, ele mostrará uma mensagem de sucesso:
Success: no issues found in 1 source file
Dica de tipo e inferência de tipo
Ao definir uma variável, você pode adicionar uma dica de tipo como esta:
name: str = 'John'
O tipo da variável name
é str
. Se você atribuir um valor que não seja uma string à variável name
, o verificador de tipo estático emitirá um erro. Por exemplo:
name: str = 'Hello'
name = 100
Erro:
app.py:2: error: Incompatible types in assignment (expression has type "int", variable has type "str")
Found 1 error in 1 file (checked 1 source file)
Adicionar um tipo a uma variável é desnecessário porque os verificadores de tipo estático geralmente podem inferir o tipo com base no valor atribuído à variável.
Neste exemplo, o valor do nome é uma string literal para que o verificador de tipo estático infira o tipo da variável de nome como str. Por exemplo:
name = 'Hello'
name = 100
Vai dar o mesmo erro:
app.py:2: error: Incompatible types in assignment (expression has type "int", variable has type "str")
Found 1 error in 1 file (checked 1 source file)
Adicionando dicas de tipo para vários tipos
A seguinte função add()
retorna a soma de dois números:
def add(x, y):
return x + y
Os números podem ser inteiros ou flutuantes. Para definir dicas de tipo para vários tipos, você pode usar Union
no módulo typing
.
Primeiro, importe Union
do módulo typing
:
from typing import Union
Em segundo lugar, use Union
para criar um tipo de união que inclua int
e float
:
def add(x: Union[int, float], y: Union[int, float]) -> Union[int, float]:
return x + y
Aqui está o código-fonte completo:
from typing import Union
def add(x: Union[int, float], y: Union[int, float]) -> Union[int, float]:
return x + y
A partir do Python 3.10, você pode usar o X | Sintaxe Y para criar um tipo de união, por exemplo:
def add(x: int | float, y: int | float) -> int | float:
return x + y
Alias de tipo
O Python permite que você atribua um alias a um tipo e use o alias para dicas de tipo. Por exemplo:
from typing import Union
number = Union[int, float]
def add(x: number, y: number) -> number:
return x + y
Neste exemplo, atribuímos um alias Union[int, float]
ao tipo Number
e usamos o alias Number
na função add().
Adicionando dicas de tipo para listas, dicionários e conjuntos
Você pode usar os seguintes tipos integrados para definir as dicas de tipo para uma lista, dicionário e conjunto:
- lista
- dicionário
- conjunto
Se você digitar uma dica de variável como uma lista, mas depois atribuir um dicionário a ela, receberá um erro:
ratings: list = [1, 2, 3]
ratings = {1: 'Bad', 2: 'average', 3: 'Good'}
Erro:
app.py:3: error: Incompatible types in assignment (expression has type "Dict[int, str]", variable has type "List[Any]")
Found 1 error in 1 file (checked 1 source file)
Para especificar os tipos de valores na lista, dicionário e conjuntos, você pode usar aliases de tipo do módulo de typing:
Alias de tipo | Tipo embutido |
---|---|
Lista | lista |
tupla | tupla |
Dict | dict |
Set | set |
Frozenset | frozenset |
Sequence | Para lista, tupla e qualquer outro tipo de dados de sequência. |
Mapping | Para dicionário (dict), conjunto, frozenset e qualquer outro tipo de dados de mapeamento |
ByteString | tipos bytes, bytearray e memoryview. |
Por exemplo, o seguinte define uma lista de números inteiros:
from typing import List
ratings: List[int] = [1, 2, 3]
nenhum tipo
Se uma função não retornar explicitamente um valor, você pode usar None para uma dica de tipo do valor de retorno. Por exemplo:
def log(message: str) -> None:
print(message)
Resumo
- Use dicas de tipo e ferramentas de verificação de tipo estático para tornar seu código mais robusto.