Dicas de tipo de Python

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.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *