Como Verificar se uma Função Aceita Certos Argumentos em Python

PythonBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá como verificar se uma função Python aceita determinados argumentos, explorando as assinaturas de funções. O laboratório utiliza o módulo inspect para acessar e inspecionar assinaturas de funções, fornecendo informações valiosas sobre os argumentos esperados e os valores de retorno de uma função.

O laboratório guia você na criação de um script Python com uma função de exemplo e, em seguida, usa inspect.signature() para obter e imprimir a assinatura da função. Você também aprenderá como interpretar a saída para entender os parâmetros da função e o tipo de retorno. Finalmente, o laboratório demonstrará como testar a passagem de argumentos usando blocos try-except.

Aprenda Sobre Assinaturas de Funções

Nesta etapa, você aprenderá sobre assinaturas de funções em Python. As assinaturas de funções fornecem informações valiosas sobre os argumentos esperados e os valores de retorno de uma função. Compreender as assinaturas de funções é crucial para escrever código limpo, sustentável e livre de erros.

Uma assinatura de função inclui as seguintes informações:

  • Nome da Função: O nome da função.
  • Parâmetros: Os nomes e tipos dos argumentos que a função aceita.
  • Tipo de Retorno: O tipo de valor que a função retorna (se houver).

Python oferece várias maneiras de acessar e inspecionar assinaturas de funções. Um dos métodos mais comuns e poderosos é usar o módulo inspect. Vamos explorar como usar o módulo inspect para aprender sobre assinaturas de funções.

Primeiro, vamos criar um script Python simples chamado my_function.py em seu diretório ~/project usando o editor VS Code. Este script definirá uma função e, em seguida, usará o módulo inspect para examinar sua assinatura.

## filename: ~/project/my_function.py
import inspect

def add_numbers(x: int, y: int) -> int:
    """This function adds two numbers and returns the result."""
    return x + y

sig = inspect.signature(add_numbers)

print(sig)

Neste script:

  • Importamos o módulo inspect.
  • Definimos uma função chamada add_numbers que recebe dois argumentos inteiros (x e y) e retorna sua soma como um inteiro.
  • Usamos dicas de tipo (x: int, y: int, -> int) para especificar os tipos esperados dos argumentos e o valor de retorno.
  • Usamos inspect.signature() para obter a assinatura da função add_numbers e armazená-la na variável sig.
  • Imprimimos a assinatura no console.

Agora, vamos executar o script usando o comando python:

python ~/project/my_function.py

Você deve ver a seguinte saída:

(x: int, y: int) -> int

Esta saída representa a assinatura da função add_numbers. Ela mostra que a função aceita dois parâmetros, x e y, ambos esperados como inteiros, e que a função retorna um inteiro.

Compreender as assinaturas de funções ajuda você a usar as funções corretamente e evitar erros comuns. Nas próximas etapas, você aprenderá mais sobre como usar o módulo inspect para extrair informações detalhadas das assinaturas de funções.

Use inspect.signature()

Na etapa anterior, você aprendeu como obter a assinatura de uma função usando inspect.signature(). Nesta etapa, você se aprofundará em como usar o objeto de assinatura para extrair informações mais detalhadas sobre os parâmetros da função.

A função inspect.signature() retorna um objeto Signature, que possui vários atributos e métodos úteis para inspecionar os parâmetros da função. Vamos modificar o script my_function.py para explorar esses recursos.

Abra o arquivo my_function.py em seu diretório ~/project usando o editor VS Code e modifique-o da seguinte forma:

## filename: ~/project/my_function.py
import inspect

def add_numbers(x: int, y: int = 10) -> int:
    """This function adds two numbers and returns the result."""
    return x + y

sig = inspect.signature(add_numbers)

for param in sig.parameters.values():
    print(f"Parameter Name: {param.name}")
    print(f"Parameter Default: {param.default}")
    print(f"Parameter Annotation: {param.annotation}")
    print(f"Parameter Kind: {param.kind}")
    print("-" * 20)

Neste script modificado:

  • Adicionamos um valor padrão de 10 ao parâmetro y (y: int = 10).
  • Iteramos sobre o atributo parameters do objeto Signature, que é um dicionário ordenado de objetos Parameter.
  • Para cada objeto Parameter, imprimimos seus atributos name, default, annotation e kind.

Agora, execute o script usando o comando python:

python ~/project/my_function.py

Você deve ver a seguinte saída:

Parameter Name: x
Parameter Default: <class 'inspect._empty'>
Parameter Annotation: <class 'int'>
Parameter Kind: POSITIONAL_OR_KEYWORD
--------------------
Parameter Name: y
Parameter Default: 10
Parameter Annotation: <class 'int'>
Parameter Kind: POSITIONAL_OR_KEYWORD
--------------------

Vamos analisar a saída:

  • Parameter Name: O nome do parâmetro (x e y).
  • Parameter Default: O valor padrão do parâmetro. Se um parâmetro não tiver um valor padrão, isso será inspect._empty.
  • Parameter Annotation: A anotação de tipo do parâmetro (por exemplo, <class 'int'>).
  • Parameter Kind: O tipo de parâmetro, que pode ser POSITIONAL_OR_KEYWORD, VAR_POSITIONAL, VAR_KEYWORD, KEYWORD_ONLY ou POSITIONAL_ONLY. Neste caso, tanto x quanto y são POSITIONAL_OR_KEYWORD, o que significa que podem ser passados como argumentos posicionais ou de palavra-chave.

Ao usar inspect.signature(), você pode obter uma compreensão mais profunda dos parâmetros de uma função e suas propriedades. Essa informação é valiosa para escrever código que interage com funções corretamente e para documentar seu código de forma eficaz.

Teste a Passagem de Argumentos com try-except

Nesta etapa, você aprenderá como usar blocos try-except para lidar com possíveis erros ao passar argumentos para uma função. Isso é especialmente importante ao lidar com entrada do usuário ou dados externos, onde o tipo de dados ou formato pode não ser o que a função espera.

Vamos modificar o script my_function.py para incluir tratamento de erros usando try-except. Tentaremos chamar a função add_numbers com argumentos inválidos e capturar o TypeError resultante.

Abra o arquivo my_function.py em seu diretório ~/project usando o editor VS Code e modifique-o da seguinte forma:

## filename: ~/project/my_function.py
import inspect

def add_numbers(x: int, y: int = 10) -> int:
    """This function adds two numbers and returns the result."""
    return x + y

try:
    result = add_numbers("hello", 5)
    print(f"Result: {result}")
except TypeError as e:
    print(f"Error: {e}")

try:
    result = add_numbers(5, "world")
    print(f"Result: {result}")
except TypeError as e:
    print(f"Error: {e}")

try:
    result = add_numbers(5, 5)
    print(f"Result: {result}")
except TypeError as e:
    print(f"Error: {e}")

Neste script modificado:

  • Envolvemos as chamadas para add_numbers em blocos try-except.
  • Tentamos chamar add_numbers com uma string como o primeiro argumento e um inteiro como o segundo argumento.
  • Tentamos chamar add_numbers com um inteiro como o primeiro argumento e uma string como o segundo argumento.
  • Tentamos chamar add_numbers com dois inteiros como argumentos.
  • Se um TypeError ocorrer (o que acontecerá quando passarmos uma string em vez de um inteiro), capturamos a exceção e imprimimos uma mensagem de erro.
  • Se nenhum TypeError ocorrer, imprimimos o resultado da chamada da função.

Agora, execute o script usando o comando python:

python ~/project/my_function.py

Você deve ver a seguinte saída:

Error: unsupported operand type(s) for +: 'str' and 'int'
Error: unsupported operand type(s) for +: 'int' and 'str'
Result: 10

Esta saída demonstra como os blocos try-except podem ser usados para lidar graciosamente com erros que ocorrem ao passar argumentos inválidos para uma função. As duas primeiras chamadas para add_numbers resultam em exceções TypeError, que são capturadas e tratadas pelos blocos except. A terceira chamada para add_numbers com dois inteiros é executada com sucesso e o resultado é impresso.

Usar blocos try-except é uma prática recomendada para escrever código robusto e confiável. Ele permite que você antecipe possíveis erros e os trate de uma forma que impeça seu programa de travar.

Resumo

Neste laboratório, você aprendeu sobre assinaturas de funções em Python e como elas fornecem informações sobre os argumentos esperados e os valores de retorno de uma função. Compreender as assinaturas de funções é crucial para escrever código limpo e de fácil manutenção.

O laboratório demonstra como usar o módulo inspect, especificamente a função inspect.signature(), para recuperar e examinar a assinatura de uma função Python. Você cria uma função simples com dicas de tipo (type hints) e, em seguida, usa inspect.signature() para imprimir a assinatura da função no console, revelando os tipos de argumentos esperados e o tipo de retorno.