Python & AI Tutorials Logo
Programação Python

19. Definindo e Chamando Funções

19.1) O Que São Funções e Por Que Elas Importam

Uma função(function) é um bloco nomeado de código que realiza uma tarefa específica. Você já vem usando funções ao longo deste livro — print(), input(), len(), type(), e muitas outras. Essas são funções embutidas (built-in functions) que o Python fornece. Agora você vai aprender a criar suas próprias funções personalizadas (custom functions) para organizar seu código e torná-lo reutilizável.

Por Que Funções Importam

Funções são fundamentais para escrever programas claros e fáceis de manter. Elas oferecem vários benefícios críticos:

1. Reutilização de Código

Sem funções, você precisaria copiar e colar o mesmo código toda vez que quisesse realizar uma tarefa. Considere calcular a área de um retângulo em vários lugares:

python
# Sem funções - código repetitivo
length1 = 5
width1 = 3
area1 = length1 * width1
print(f"Area 1: {area1}")
 
length2 = 8
width2 = 4
area2 = length2 * width2
print(f"Area 2: {area2}")
 
length3 = 10
width3 = 6
area3 = length3 * width3
print(f"Area 3: {area3}")

Output:

Area 1: 15
Area 2: 32
Area 3: 60

Essa repetição é cansativa e propensa a erros. Se você precisar mudar como calcula a área (talvez para incluir unidades ou arredondamento), teria que atualizar cada lugar. Funções resolvem esse problema permitindo que você escreva o código uma vez e o use muitas vezes.

2. Organização de Código

Funções quebram programas grandes em partes menores e gerenciáveis. Cada função lida com uma tarefa específica, deixando seu código mais fácil de entender e manter. Em vez de um script longo com centenas de linhas, você pode organizar operações relacionadas em funções nomeadas que comunicam claramente seu propósito.

3. Abstração (abstraction)

Funções escondem detalhes de implementação por trás de uma interface simples. Quando você chama len(my_list), você não precisa saber como o Python conta os elementos — você só obtém o resultado. Da mesma forma, suas funções podem oferecer interfaces simples para operações complexas, deixando seu código mais fácil de usar e entender.

4. Testes e Depuração (debugging)

Funções facilitam testar partes individuais do seu programa. Você pode verificar se cada função funciona corretamente de forma isolada antes de combiná-las em um programa maior. Quando algo dá errado, funções ajudam você a reduzir onde o problema está acontecendo.

Ao longo do restante deste capítulo, você vai aprender como definir suas próprias funções, passar informações para elas, obter resultados de volta e documentá-las de forma clara. Essas habilidades são essenciais para escrever código Python profissional.

19.2) Definindo Funções com def

Para criar uma função em Python, você usa a palavra-chave def (abreviação de "define"). A estrutura básica de uma definição de função parece com isto:

python
def function_name():
    # Bloco de código que roda quando a função é chamada
    statement1
    statement2
    # ... mais instruções

Vamos detalhar cada parte:

  • def: A palavra-chave que diz ao Python que você está definindo uma função
  • function_name: O nome que você escolhe para sua função (segue as mesmas regras dos nomes de variáveis)
  • (): Parênteses que vão eventualmente conter parâmetros (vamos cobrir isso na próxima seção)
  • :: Dois-pontos que marcam o fim do cabeçalho da função
  • Bloco de código indentado: As instruções que compõem o corpo da função (devem estar indentadas)

Sua Primeira Função

Aqui está uma função simples que imprime uma saudação:

python
def greet():
    print("Hello!")
    print("Welcome to Python functions.")
 
# Chame a função
greet()

Output:

Hello!
Welcome to Python functions.

Quando você define uma função, o Python lembra dela, mas não executa o código dentro imediatamente. O código só roda quando você chama (call) a função escrevendo seu nome seguido de parênteses: greet().

Convenções de Nomeação de Funções

Nomes de funções seguem as mesmas regras dos nomes de variáveis (como aprendemos no Capítulo 3):

  • Use letras minúsculas
  • Separe palavras com underscores (snake_case)
  • Comece com uma letra ou underscore, não com um dígito
  • Use nomes descritivos que indiquem o que a função faz
python
# Bons nomes de funções
def calculate_total():
    pass
 
def get_user_age():
    pass
 
def display_menu():
    pass
 
# Nomes ruins de funções (mas sintaticamente válidos)
def x():  # Não é descritivo
    pass
 
def CalculateTotal():  # Deve usar minúsculas
    pass
 
def calc():  # Abreviação demais
    pass

Nota: Usamos pass aqui como um placeholder (como aprendemos no Capítulo 8). Ele não faz nada, mas permite que a definição da função fique sintaticamente completa.

Funções Podem Conter Qualquer Código

O corpo de uma função pode conter qualquer instrução Python que você tenha aprendido até agora: atribuições de variáveis, condicionais, loops, e até chamadas para outras funções.

python
def check_temperature():
    temperature = 72
    if temperature > 75:
        print("It's warm.")
    elif temperature > 60:
        print("It's comfortable.")
    else:
        print("It's cool.")
 
check_temperature()

Output:

It's comfortable.

Múltiplas Definições de Função

Você pode definir quantas funções precisar no seu programa. Cada função é independente e pode ser chamada separadamente:

python
def morning_greeting():
    print("Good morning!")
 
def evening_greeting():
    print("Good evening!")
 
# Chame cada função
morning_greeting()
evening_greeting()

Output:

Good morning!
Good evening!

Ordem de Definição de Funções

Em Python, você deve definir uma função antes de chamá-la. O interpretador Python lê seu código de cima para baixo, então se você tentar chamar uma função antes de defini-la, você vai receber um erro:

python
# WARNING: This will cause a NameError - for demonstration only
# PROBLEM: Function called before it's defined
say_hello()  # NameError: name 'say_hello' is not defined
 
def say_hello():
    print("Hello!")

A ordem correta é definir primeiro e depois chamar:

python
# Correto: defina primeiro
def say_hello():
    print("Hello!")
 
# Depois chame
say_hello()

Output:

Hello!

No entanto, funções podem chamar outras funções que são definidas mais tarde no arquivo, desde que essas chamadas aconteçam depois de todas as definições:

python
def first_function():
    print("First function")
    second_function()  # Isso está ok - chamada em runtime
 
def second_function():
    print("Second function")
 
# Ambas as funções estão definidas antes de chamarmos a primeira
first_function()

Output:

First function
Second function

Funções Criam Escopo Local (local scope)

Variáveis criadas dentro de uma função existem apenas dentro dessa função. Isso é chamado de escopo local (local scope) (vamos explorar isso em detalhes no Capítulo 21). Por enquanto, entenda que o que acontece dentro de uma função fica dentro da função:

python
def create_message():
    message = "This is local"
    print(message)
 
create_message()
 
# Isso causaria um erro:
# print(message)  # NameError: name 'message' is not defined

Output:

This is local

A variável message existe apenas enquanto a função está rodando. Quando a função termina, a variável desaparece.

Funções Vazias com pass

Às vezes você quer definir a estrutura de uma função, mas implementá-la depois. Use pass como placeholder:

python
def future_feature():
    pass  # TODO: Implemente isso depois
 
# A função existe e pode ser chamada, mas não faz nada
future_feature()  # Roda sem erro, não faz nada

Isso é útil quando você está esboçando a estrutura do seu programa antes de preencher os detalhes.

19.3) Chamando Funções e Passando Argumentos

Definir uma função cria um pedaço reutilizável de código, mas para deixar funções realmente poderosas, você precisa passar informações para elas. Essas informações são passadas por meio de argumentos (arguments).

Parâmetros vs Argumentos

Antes de continuar, vamos esclarecer dois termos que muitas vezes são confundidos:

  • Parâmetro (parameter): Um nome de variável na definição da função que vai receber um valor
  • Argumento (argument): O valor real que você passa para a função quando a chama
python
def greet(name):  # 'name' é um parâmetro
    print(f"Hello, {name}!")
 
greet("Alice")  # "Alice" é um argumento

Output:

Hello, Alice!

Pense em parâmetros como placeholders e argumentos como os dados reais que preenchem esses placeholders.

Definindo Funções com Parâmetros

Para definir uma função que aceita entrada, adicione nomes de parâmetros dentro dos parênteses:

python
def greet_person(name):
    print(f"Hello, {name}!")
    print("Nice to meet you.")
 
# Chame com argumentos diferentes
greet_person("Alice")
print()  # Linha em branco para legibilidade
greet_person("Bob")

Output:

Hello, Alice!
Nice to meet you.
 
Hello, Bob!
Nice to meet you.

O parâmetro name atua como uma variável dentro da função. Cada vez que você chama a função, name assume o valor do argumento que você fornece.

Múltiplos Parâmetros

Funções podem aceitar múltiplos parâmetros, separados por vírgulas:

python
def calculate_rectangle_area(length, width):
    area = length * width
    print(f"A rectangle with length {length} and width {width}")
    print(f"has an area of {area} square units.")
 
calculate_rectangle_area(5, 3)
print()
calculate_rectangle_area(10, 7)

Output:

A rectangle with length 5 and width 3
has an area of 15 square units.
 
A rectangle with length 10 and width 7
has an area of 70 square units.

Ao chamar uma função com múltiplos parâmetros, a ordem importa. O primeiro argumento vai para o primeiro parâmetro, o segundo argumento para o segundo parâmetro, e assim por diante. Esses são chamados de argumentos posicionais (positional arguments).

Argumentos Posicionais

Com argumentos posicionais, o Python associa argumentos a parâmetros com base na posição:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
describe_pet("dog", "Buddy")
print()
describe_pet("cat", "Whiskers")

Output:

I have a dog.
My dog's name is Buddy.
 
I have a cat.
My cat's name is Whiskers.

Se você trocar a ordem, vai ter resultados inesperados:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
# Argumentos na ordem errada
describe_pet("Buddy", "dog")

Output:

I have a Buddy.
My Buddy's name is dog.

Isso é tecnicamente Python válido, mas produz uma saída sem sentido porque os argumentos estão nas posições erradas.

Argumentos Nomeados (keyword arguments)

Para evitar erros relacionados à posição, você pode usar argumentos nomeados (keyword arguments) nomeando explicitamente os parâmetros ao chamar a função:

python
def describe_pet(animal_type, pet_name):
    print(f"I have a {animal_type}.")
    print(f"My {animal_type}'s name is {pet_name}.")
 
# Usando argumentos nomeados - a ordem não importa
describe_pet(animal_type="dog", pet_name="Buddy")
print()
describe_pet(pet_name="Whiskers", animal_type="cat")

Output:

I have a dog.
My dog's name is Buddy.
 
I have a cat.
My cat's name is Whiskers.

Com argumentos nomeados, a ordem não importa porque o Python associa argumentos a parâmetros pelo nome, não pela posição.

Misturando Argumentos Posicionais e Nomeados

Você pode misturar argumentos posicionais e nomeados em uma única chamada de função, mas argumentos posicionais devem vir primeiro:

python
def create_profile(username, email, age):
    print(f"Username: {username}")
    print(f"Email: {email}")
    print(f"Age: {age}")
 
# Misturando argumentos posicionais e nomeados
create_profile("alice123", email="alice@example.com", age=25)

Output:

Username: alice123
Email: alice@example.com
Age: 25

No entanto, você não pode colocar argumentos posicionais depois de argumentos nomeados:

python
# WARNING: This will cause a SyntaxError - for demonstration only
# PROBLEM: Positional argument after keyword argument
# create_profile(username="alice123", "alice@example.com", 25)
# SyntaxError: positional argument follows keyword argument

A Quantidade de Argumentos Deve Bater

Quando você chama uma função, você deve fornecer o número correto de argumentos (a menos que a função tenha valores padrão, o que veremos no Capítulo 20):

python
def add_numbers(a, b):
    result = a + b
    print(f"{a} + {b} = {result}")
 
add_numbers(5, 3)  # Correto: 2 argumentos para 2 parâmetros

Output:

5 + 3 = 8

Fornecer argumentos de menos ou demais causa um erro:

python
# WARNING: These will cause TypeErrors - for demonstration only
 
# PROBLEM: Too few arguments
# add_numbers(5)
# TypeError: add_numbers() missing 1 required positional argument: 'b'
 
# PROBLEM: Too many arguments
# add_numbers(5, 3, 2)
# TypeError: add_numbers() takes 2 positional arguments but 3 were given

Usando Expressões como Argumentos

Argumentos não precisam ser valores simples — você pode usar qualquer expressão:

python
def display_total(price, quantity):
    total = price * quantity
    print(f"Total cost: ${total:.2f}")
 
# Usando expressões como argumentos
base_price = 10
display_total(base_price * 1.1, 5)  # Preço com markup de 10%
display_total(15 + 5, 3 * 2)        # Ambos os argumentos são expressões

Output:

Total cost: $55.00
Total cost: $120.00

O Python avalia cada expressão primeiro e depois passa os valores resultantes para a função.

Chamando Funções de Dentro de Funções

Funções podem chamar outras funções, criando uma hierarquia de operações. Esta é uma técnica poderosa que permite dividir tarefas complexas em partes menores e gerenciáveis.

Aqui está um exemplo com cálculo de área de cômodos:

python
def calculate_area(length, width):
    return length * width
 
def display_room_info(room_name, length, width):
    area = calculate_area(length, width)
    print(f"Room: {room_name}")
    print(f"Dimensions: {length} x {width}")
    print(f"Area: {area} square feet")
 
display_room_info("Living Room", 15, 12)

Output:

Room: Living Room
Dimensions: 15 x 12
Area: 180 square feet

Nota: Estamos usando return aqui, o que vamos explorar em detalhes na próxima seção. Por enquanto, entenda que calculate_area() envia seu resultado de volta para a função que a chamou.

Aqui está outro exemplo mostrando como funções podem se basear umas nas outras — um sistema de conversão de temperatura:

python
def celsius_to_fahrenheit(celsius):
    return (celsius * 9/5) + 32
 
def format_temperature(fahrenheit):
    return f"{fahrenheit:.1f}°F"
 
def display_temperature_conversion(celsius):
    fahrenheit = celsius_to_fahrenheit(celsius)
    formatted = format_temperature(fahrenheit)
    print(f"{celsius}°C equals {formatted}")
 
# Use o sistema completo de conversão
display_temperature_conversion(25)
display_temperature_conversion(0)
display_temperature_conversion(100)

Output:

25°C equals 77.0°F
0°C equals 32.0°F
100°C equals 212.0°F

Neste exemplo, display_temperature_conversion() chama celsius_to_fahrenheit() para fazer a conversão, e depois chama format_temperature() para formatar o resultado. Cada função tem uma única responsabilidade clara, tornando o código fácil de entender e manter.

19.4) Usando return para Enviar Resultados de Volta

Até agora, nossas funções realizaram ações (como imprimir), mas não enviaram valores de volta para o código que as chamou. A instrução return permite que uma função compute um resultado e o envie de volta para quem chamou.

Instrução return Básica

Aqui está uma função simples que calcula e retorna um valor:

python
def add_numbers(a, b):
    result = a + b
    return result
 
# Capture o valor retornado
sum_value = add_numbers(5, 3)
print(f"The sum is: {sum_value}")

Output:

The sum is: 8

Quando o Python encontra uma instrução return, duas coisas acontecem:

  1. A função para de executar imediatamente (qualquer código depois de return é ignorado)
  2. O valor especificado é enviado de volta para quem chamou

Retornando Valores Diretamente

Você não precisa armazenar o resultado em uma variável antes de retorná-lo. Você pode retornar uma expressão diretamente:

python
def multiply(a, b):
    return a * b
 
result = multiply(4, 7)
print(f"4 × 7 = {result}")

Output:

4 × 7 = 28

Isso é mais conciso e é o estilo preferido para cálculos simples.

Usando Valores Retornados

Quando uma função retorna um valor, você pode usar esse valor em qualquer lugar onde usaria qualquer outro valor:

python
def calculate_discount(price, discount_percent):
    discount_amount = price * (discount_percent / 100)
    return discount_amount
 
original_price = 100
discount = calculate_discount(original_price, 20)
 
# Use o valor retornado em cálculos
final_price = original_price - discount
print(f"Original price: ${original_price:.2f}")
print(f"Discount: ${discount:.2f}")
print(f"Final price: ${final_price:.2f}")

Output:

Original price: $100.00
Discount: $20.00
Final price: $80.00

return Sai da Função Imediatamente

Quando o Python executa uma instrução return, a função para imediatamente. Qualquer código após o return nunca é executado:

python
def check_age(age):
    if age < 18:
        return "Minor"
    # Esta linha só roda se age >= 18
    return "Adult"
 
print(check_age(15))
print(check_age(25))

Output:

Minor
Adult

Esse comportamento é útil para lidar com diferentes casos em uma função. Quando você determina o resultado, você pode retornar imediatamente sem precisar checar condições adicionais.

Aqui está um exemplo que demonstra como return para a execução:

python
def process_number(n):
    if n < 0:
        return "Negative"
    print("This line runs for non-negative numbers")
    if n == 0:
        return "Zero"
    print("This line runs for positive numbers")
    return "Positive"
 
print(process_number(-5))
print()
print(process_number(0))
print()
print(process_number(10))

Output:

Negative
 
This line runs for non-negative numbers
Zero
 
This line runs for non-negative numbers
This line runs for positive numbers
Positive

Funções Sem return

Se uma função não tem uma instrução return, ou se ela tem um return sem valor, a função retorna None:

python
def greet(name):
    print(f"Hello, {name}!")
    # Sem instrução return
 
result = greet("Alice")
print(f"The function returned: {result}")

Output:

Hello, Alice!
The function returned: None

Da mesma forma, um return “nu” (sem valor) também retorna None:

python
def process_data(data):
    if not data:
        return  # Saída antecipada, retorna None
    print(f"Processing: {data}")
    return "Success"
 
result1 = process_data("")
result2 = process_data("some data")
 
print(f"Result 1: {result1}")
print(f"Result 2: {result2}")

Output:

Processing: some data
Result 1: None
Result 2: Success

Retornando Múltiplos Valores

Funções Python podem retornar múltiplos valores separando-os com vírgulas. O Python automaticamente empacota isso em uma tupla (tuple) (como aprendemos no Capítulo 15):

python
def calculate_rectangle(length, width):
    area = length * width
    perimeter = 2 * (length + width)
    return area, perimeter
 
# Desempacote a tupla retornada
rect_area, rect_perimeter = calculate_rectangle(5, 3)
print(f"Area: {rect_area}")
print(f"Perimeter: {rect_perimeter}")

Output:

Area: 15
Perimeter: 16

Você também pode capturar a tupla como um único valor:

python
def get_student_info():
    name = "Alice"
    age = 20
    grade = "A"
    return name, age, grade
 
# Capture como uma tupla
student = get_student_info()
print(f"Student info: {student}")
print(f"Name: {student[0]}")

Output:

Student info: ('Alice', 20, 'A')
Name: Alice

Retornando Tipos Diferentes

Uma função pode retornar tipos diferentes de valores dependendo da situação:

python
def divide(a, b):
    if b == 0:
        return "Error: Division by zero"
    return a / b
 
result1 = divide(10, 2)
result2 = divide(10, 0)
 
print(f"10 / 2 = {result1}")
print(f"10 / 0 = {result2}")

Output:

10 / 2 = 5.0
10 / 0 = Error: Division by zero

Embora isso funcione, em geral é uma prática melhor lidar com erros de forma diferente (vamos aprender sobre exceções na Parte VII). Por enquanto, entenda que funções podem retornar tipos diferentes, embora muitas vezes seja mais claro ser consistente.

19.5) Documentando Funções com Docstrings

Conforme seus programas crescem e você cria mais funções, fica crucial documentar o que cada função faz. O Python fornece uma forma embutida de documentar funções usando docstrings (documentation strings).

O Que É uma Docstring?

Uma docstring é um literal de string que aparece como a primeira instrução em uma função (ou módulo, classe ou método). Ela descreve o que a função faz, quais parâmetros ela aceita e o que retorna. Docstrings são colocadas entre aspas triplas (""" ou '''), o que permite que elas se estendam por múltiplas linhas.

python
def calculate_area(length, width):
    """Calculate the area of a rectangle.
    
    Takes the length and width of a rectangle and returns the area.
    """
    return length * width

Por Que Docstrings Importam

Docstrings servem a vários propósitos importantes:

  1. Autodocumentação (self-documentation): Elas explicam o que sua função faz sem exigir que leitores analisem o código
  2. Suporte da IDE: Muitas ferramentas de desenvolvimento exibem docstrings como tooltips quando você usa uma função
  3. Função help(): A função embutida help() do Python exibe docstrings
  4. Prática profissional: Código bem documentado é mais fácil de manter e compartilhar com outras pessoas

Formato Básico de Docstring

Para funções simples, uma docstring de uma linha é suficiente:

python
def greet(name):
    """Print a personalized greeting."""
    print(f"Hello, {name}!")
 
# Acesse a docstring
print(greet.__doc__)

Output:

Print a personalized greeting.

A docstring deve ser uma descrição concisa do que a função faz, escrita como um comando ("Calculate...", "Return...", "Print...") em vez de uma descrição ("This function calculates...").

Docstrings de Múltiplas Linhas

Para funções mais complexas, use docstrings de múltiplas linhas que incluam:

  • Um resumo breve na primeira linha
  • Uma linha em branco
  • Uma descrição mais detalhada
  • Informações sobre parâmetros
  • Informações sobre valores de retorno
python
def calculate_discount(price, discount_percent):
    """Calculate the discounted price.
    
    Takes an original price and a discount percentage, then returns
    the amount of discount that should be applied.
    
    Parameters:
    price (float): The original price before discount
    discount_percent (float): The discount percentage (0-100)
    
    Returns:
    float: The discount amount in the same currency as the price
    """
    return price * (discount_percent / 100)
 
# Use help() para ver a docstring completa
help(calculate_discount)

Output:

Help on function calculate_discount in module __main__:
 
calculate_discount(price, discount_percent)
    Calculate the discounted price.
    
    Takes an original price and a discount percentage, then returns
    the amount of discount that should be applied.
    
    Parameters:
    price (float): The original price before discount
    discount_percent (float): The discount percentage (0-100)
    
    Returns:
    float: The discount amount in the same currency as the price

Convenções de Docstring

O Python tem convenções estabelecidas para escrever docstrings (documentadas na PEP 257). Aqui estão as diretrizes principais:

1. Use aspas duplas triplas: """docstring"""

python
def good_example():
    """This follows the convention."""
    pass
 
def also_valid():
    '''This works but is less common.'''
    pass

2. Docstrings de uma linha devem caber em uma linha:

python
def add(a, b):
    """Return the sum of a and b."""
    return a + b

3. Docstrings de múltiplas linhas devem ter uma linha de resumo e depois uma linha em branco:

python
def process_order(order_id, items):
    """Process a customer order and update inventory.
    
    This function validates the order, checks inventory availability,
    calculates the total cost, and updates the inventory database.
    
    Parameters:
    order_id (str): Unique identifier for the order
    items (list): List of item dictionaries with 'product' and 'quantity'
    
    Returns:
    dict: Order summary with 'total', 'status', and 'confirmation_number'
    """
    # Implementação da função aqui
    pass

Descrevendo Parâmetros e Valores de Retorno

Ao documentar parâmetros e valores de retorno, seja específico sobre:

  • Nomes de parâmetros: Correspondam aos nomes reais dos parâmetros na função
  • Tipos: Que tipo de dado é esperado (vamos aprender sobre type hints no Capítulo 43)
  • Propósito: Para que o parâmetro é usado
  • Valor de retorno: O que a função retorna e sob quais condições
python
def find_student(student_id, students):
    """Find a student by ID in a list of student records.
    
    Parameters:
    student_id (int): The unique ID number of the student to find
    students (list): List of student dictionaries, each containing 'id' and 'name'
    
    Returns:
    dict: The student dictionary if found, None if not found
    """
    for student in students:
        if student['id'] == student_id:
            return student
    return None

Docstrings para Funções com Múltiplos Tipos de Retorno

Quando uma função pode retornar tipos diferentes dependendo da situação, documente todas as possibilidades:

python
def safe_divide(a, b):
    """Divide two numbers with error handling.
    
    Parameters:
    a (float): The dividend
    b (float): The divisor
    
    Returns:
    float: The quotient if division is successful
    str: An error message if b is zero
    """
    if b == 0:
        return "Error: Cannot divide by zero"
    return a / b

Acessando Docstrings

Você pode acessar a docstring de uma função de três maneiras:

1. Usando o atributo __doc__:

python
def example():
    """This is an example function."""
    pass
 
print(example.__doc__)

Output:

This is an example function.

2. Usando a função help():

python
def calculate_bmi(weight, height):
    """Calculate Body Mass Index.
    
    Parameters:
    weight (float): Weight in kilograms
    height (float): Height in meters
    
    Returns:
    float: BMI value
    """
    return weight / (height ** 2)
 
help(calculate_bmi)

Output:

Help on function calculate_bmi in module __main__:
 
calculate_bmi(weight, height)
    Calculate Body Mass Index.
    
    Parameters:
    weight (float): Weight in kilograms
    height (float): Height in meters
    
    Returns:
    float: BMI value

3. Em ambientes de desenvolvimento interativos: A maioria das IDEs e editores de código exibem docstrings como tooltips quando você passa o mouse por cima ou digita o nome de uma função.

Quando Escrever Docstrings

Você deve escrever docstrings para:

  • Todas as funções públicas (public functions): Funções que devem ser usadas por outras partes do seu programa ou por outros programadores
  • Funções complexas: Qualquer função cujo propósito ou comportamento não sejam imediatamente óbvios a partir do nome e dos parâmetros
  • Funções com parâmetros não óbvios: Quando nomes de parâmetros por si só não explicam completamente quais valores são esperados

Você pode pular docstrings para:

  • Funções muito simples e óbvias: Funções como def add(a, b): return a + b onde o nome e os parâmetros deixam o propósito cristalino
  • Funções auxiliares privadas (private helper functions): Funções internas pequenas usadas apenas dentro de uma função maior (embora até essas se beneficiem de docstrings curtas)

Docstrings Não São Comentários

Lembre que docstrings servem a um propósito diferente de comentários:

  • Docstrings: Descrevem o que uma função faz e como usá-la (a interface)
  • Comentários: Explicam como o código funciona internamente (a implementação)
python
def calculate_grade(score, total):
    """Calculate the percentage grade from a score.
    
    Parameters:
    score (int): Points earned
    total (int): Total points possible
    
    Returns:
    float: The percentage grade (0-100)
    """
    # Evite divisão por zero
    if total == 0:
        return 0.0
    
    # Calcule a porcentagem e arredonde para 2 casas decimais
    percentage = (score / total) * 100
    return round(percentage, 2)

A docstring diz aos usuários o que a função faz e como usá-la. Os comentários explicam detalhes específicos de implementação para alguém lendo o código.

Construindo Bons Hábitos de Documentação

Escrever docstrings claras é um hábito que vale muito a pena:

  • Escreva docstrings enquanto escreve funções: Não espere para depois — documente enquanto o propósito da função está fresco na sua mente
  • Mantenha docstrings atualizadas: Quando você mudar o comportamento de uma função, atualize sua docstring
  • Seja conciso, mas completo: Inclua todas as informações necessárias, mas evite verbosidade desnecessária
  • Use exemplos quando for útil: Para funções complexas, um exemplo de uso na docstring pode ser inestimável

Uma boa documentação deixa seu código mais profissional, mais fácil de manter e mais valioso para outras pessoas (incluindo você no futuro).

© 2025. Primesoft Co., Ltd.
support@primesoft.ai