Python & AI Tutorials Logo
Programación Python

19. Definir y llamar funciones

19.1) Qué son las funciones y por qué importan

Una función(function) es un bloque de código con nombre que realiza una tarea específica. Ya has estado usando funciones a lo largo de este libro—print(), input(), len(), type(), y muchas otras. Estas son funciones integradas que proporciona Python. Ahora aprenderás a crear tus propias funciones personalizadas para organizar tu código y hacerlo reutilizable.

Por qué importan las funciones

Las funciones son fundamentales para escribir programas claros y mantenibles. Proporcionan varios beneficios críticos:

1. Reutilización de código

Sin funciones, tendrías que copiar y pegar el mismo código cada vez que quieras realizar una tarea. Considera calcular el área de un rectángulo en varios lugares:

python
# Sin funciones: 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

Esta repetición es tediosa y propensa a errores. Si necesitas cambiar cómo calculas el área (quizá para incluir unidades o redondeo), tendrías que actualizar cada ubicación. Las funciones resuelven este problema al permitirte escribir el código una vez y usarlo muchas veces.

2. Organización del código

Las funciones dividen los programas grandes en piezas más pequeñas y manejables. Cada función se encarga de una tarea específica, haciendo que tu código sea más fácil de entender y mantener. En lugar de un script largo con cientos de líneas, puedes organizar operaciones relacionadas en funciones con nombre que comuniquen claramente su propósito.

3. Abstracción(abstraction)

Las funciones ocultan los detalles de implementación detrás de una interfaz simple. Cuando llamas a len(my_list), no necesitas saber cómo Python cuenta los elementos—simplemente obtienes el resultado. De forma similar, tus funciones pueden proporcionar interfaces simples para operaciones complejas, haciendo que tu código sea más fácil de usar y entender.

4. Pruebas(testing) y depuración(debugging)

Las funciones facilitan probar piezas individuales de tu programa. Puedes verificar que cada función funciona correctamente de forma aislada antes de combinarlas en un programa más grande. Cuando algo sale mal, las funciones te ayudan a acotar dónde está ocurriendo el problema.

A lo largo del resto de este capítulo, aprenderás a definir tus propias funciones, pasarles información, recuperar resultados y documentarlas claramente. Estas habilidades son esenciales para escribir código Python profesional.

19.2) Definir funciones con def

Para crear una función en Python, usas la palabra clave def (abreviatura de "define"). La estructura básica de una definición de función se ve así:

python
def function_name():
    # Bloque de código que se ejecuta cuando se llama a la función
    statement1
    statement2
    # ... más sentencias

Desglosemos cada parte:

  • def: La palabra clave que le dice a Python que estás definiendo una función
  • function_name: El nombre que eliges para tu función (sigue las mismas reglas que los nombres de variables)
  • (): Paréntesis que eventualmente contendrán parámetros (veremos eso en la siguiente sección)
  • :: Dos puntos que marcan el final del encabezado de la función
  • Bloque de código indentado: Las sentencias que componen el cuerpo de la función (deben estar indentadas)

Tu primera función

Aquí tienes una función simple que imprime un saludo:

python
def greet():
    print("Hello!")
    print("Welcome to Python functions.")
 
# Llama a la función
greet()

Output:

Hello!
Welcome to Python functions.

Cuando defines una función, Python la recuerda pero no ejecuta el código dentro de ella de inmediato. El código solo se ejecuta cuando llamas a la función escribiendo su nombre seguido de paréntesis: greet().

Convenciones para nombrar funciones

Los nombres de funciones siguen las mismas reglas que los nombres de variables (como aprendimos en el Capítulo 3):

  • Usa letras minúsculas
  • Separa palabras con guiones bajos (snake_case)
  • Empieza con una letra o guion bajo, no con un dígito
  • Usa nombres descriptivos que indiquen qué hace la función
python
# Buenos nombres de funciones
def calculate_total():
    pass
 
def get_user_age():
    pass
 
def display_menu():
    pass
 
# Malos nombres de funciones (pero sintácticamente válidos)
def x():  # No descriptivo
    pass
 
def CalculateTotal():  # Debería usar minúsculas
    pass
 
def calc():  # Demasiado abreviado
    pass

Nota: Usamos pass aquí como un marcador de posición (como aprendimos en el Capítulo 8). No hace nada, pero permite que la definición de la función esté completa sintácticamente.

Las funciones pueden contener cualquier código

El cuerpo de una función puede contener cualquier sentencia de Python que hayas aprendido hasta ahora: asignaciones de variables, condicionales, bucles(loop), e incluso llamadas a otras funciones.

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últiples definiciones de funciones

Puedes definir tantas funciones como necesites en tu programa. Cada función es independiente y se puede llamar por separado:

python
def morning_greeting():
    print("Good morning!")
 
def evening_greeting():
    print("Good evening!")
 
# Llama a cada función
morning_greeting()
evening_greeting()

Output:

Good morning!
Good evening!

Orden de definición de funciones

En Python, debes definir una función antes de llamarla. El intérprete de Python lee tu código de arriba hacia abajo, así que si intentas llamar a una función antes de definirla, obtendrás un error:

python
# ADVERTENCIA: Esto causará un NameError - solo para demostración
# PROBLEMA: Se llama a la función antes de que esté definida
say_hello()  # NameError: name 'say_hello' is not defined
 
def say_hello():
    print("Hello!")

El orden correcto es definir primero y luego llamar:

python
# Correcto: definir primero
def say_hello():
    print("Hello!")
 
# Luego llamar
say_hello()

Output:

Hello!

Sin embargo, las funciones pueden llamar a otras funciones que se definen más adelante en el archivo, siempre que esas llamadas ocurran después de todas las definiciones:

python
def first_function():
    print("First function")
    second_function()  # Esto está bien: se llama en tiempo de ejecución
 
def second_function():
    print("Second function")
 
# Ambas funciones están definidas antes de llamar a la primera
first_function()

Output:

First function
Second function

Las funciones crean un alcance local

Las variables creadas dentro de una función existen solo dentro de esa función. Esto se llama alcance local(local scope) (lo exploraremos en detalle en el Capítulo 21). Por ahora, entiende que lo que ocurre dentro de una función se queda dentro de la función:

python
def create_message():
    message = "This is local"
    print(message)
 
create_message()
 
# Esto causaría un error:
# print(message)  # NameError: name 'message' is not defined

Output:

This is local

La variable message existe solo mientras la función se está ejecutando. Una vez que la función termina, la variable desaparece.

Funciones vacías con pass

A veces quieres definir la estructura de una función pero implementarla más tarde. Usa pass como marcador de posición:

python
def future_feature():
    pass  # TODO: Implementa esto más tarde
 
# La función existe y se puede llamar, pero no hace nada
future_feature()  # Se ejecuta sin error, no hace nada

Esto es útil cuando bosquejas la estructura de tu programa antes de completar los detalles.

19.3) Llamar funciones y pasar argumentos

Definir una función crea una pieza de código reutilizable, pero para que las funciones sean realmente potentes, necesitas pasarles información. Esta información se pasa mediante argumentos(arguments).

Parámetros vs argumentos

Antes de continuar, aclaremos dos términos que a menudo se confunden:

  • Parámetro(parameter): Un nombre de variable en la definición de la función que recibirá un valor
  • Argumento(argument): El valor real que pasas a la función cuando la llamas
python
def greet(name):  # 'name' es un parámetro
    print(f"Hello, {name}!")
 
greet("Alice")  # "Alice" es un argumento

Output:

Hello, Alice!

Piensa en los parámetros como marcadores de posición y en los argumentos como los datos reales que llenan esos marcadores.

Definir funciones con parámetros

Para definir una función que acepte entrada, añade nombres de parámetros dentro de los paréntesis:

python
def greet_person(name):
    print(f"Hello, {name}!")
    print("Nice to meet you.")
 
# Llama con distintos argumentos
greet_person("Alice")
print()  # Línea en blanco para legibilidad
greet_person("Bob")

Output:

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

El parámetro name actúa como una variable dentro de la función. Cada vez que llamas a la función, name toma el valor del argumento que proporciones.

Múltiples parámetros

Las funciones pueden aceptar múltiples parámetros, separados por comas:

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.

Al llamar a una función con múltiples parámetros, el orden importa. El primer argumento va al primer parámetro, el segundo argumento al segundo parámetro, y así sucesivamente. Estos se llaman argumentos posicionales(positional arguments).

Argumentos posicionales

Con argumentos posicionales, Python empareja argumentos con parámetros según su posición:

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.

Si mezclas el orden, obtendrás 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 en el orden incorrecto
describe_pet("Buddy", "dog")

Output:

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

Esto es Python técnicamente válido, pero produce una salida sin sentido porque los argumentos están en posiciones incorrectas.

Argumentos con nombre

Para evitar errores relacionados con la posición, puedes usar argumentos con nombre(keyword arguments) nombrando explícitamente los parámetros cuando llamas a la función:

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}.")
 
# Usar argumentos con nombre: el orden no 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.

Con argumentos con nombre, el orden no importa porque Python empareja argumentos con parámetros por nombre, no por posición.

Mezclar argumentos posicionales y con nombre

Puedes mezclar argumentos posicionales y con nombre en una sola llamada a función, pero los argumentos posicionales deben ir primero:

python
def create_profile(username, email, age):
    print(f"Username: {username}")
    print(f"Email: {email}")
    print(f"Age: {age}")
 
# Mezclar argumentos posicionales y con nombre
create_profile("alice123", email="alice@example.com", age=25)

Output:

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

Sin embargo, no puedes poner argumentos posicionales después de argumentos con nombre:

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

La cantidad de argumentos debe coincidir

Cuando llamas a una función, debes proporcionar la cantidad correcta de argumentos (a menos que la función tenga valores por defecto, que veremos en el Capítulo 20):

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

Output:

5 + 3 = 8

Proporcionar muy pocos o demasiados argumentos causa un error:

python
# ADVERTENCIA: Estos causarán TypeErrors - solo para demostración
 
# PROBLEMA: Muy pocos argumentos
# add_numbers(5)
# TypeError: add_numbers() missing 1 required positional argument: 'b'
 
# PROBLEMA: Demasiados argumentos
# add_numbers(5, 3, 2)
# TypeError: add_numbers() takes 2 positional arguments but 3 were given

Usar expresiones como argumentos

Los argumentos no tienen que ser valores simples: puedes usar cualquier expresión:

python
def display_total(price, quantity):
    total = price * quantity
    print(f"Total cost: ${total:.2f}")
 
# Usar expresiones como argumentos
base_price = 10
display_total(base_price * 1.1, 5)  # Precio con 10% de recargo
display_total(15 + 5, 3 * 2)        # Ambos argumentos son expresiones

Output:

Total cost: $55.00
Total cost: $120.00

Python evalúa cada expresión primero y luego pasa los valores resultantes a la función.

Llamar funciones desde dentro de funciones

Las funciones pueden llamar a otras funciones, creando una jerarquía de operaciones. Esta es una técnica potente que te permite dividir tareas complejas en piezas más pequeñas y manejables.

Aquí tienes un ejemplo con el cálculo del área de una habitación:

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: Aquí estamos usando return, que exploraremos en detalle en la siguiente sección. Por ahora, entiende que calculate_area() envía su resultado de vuelta a la función que llama.

Aquí tienes otro ejemplo que muestra cómo las funciones pueden construirse unas sobre otras: un sistema de conversión 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}")
 
# Usa el sistema completo de conversión
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

En este ejemplo, display_temperature_conversion() llama a celsius_to_fahrenheit() para hacer la conversión y luego llama a format_temperature() para dar formato al resultado. Cada función tiene una única responsabilidad clara, haciendo que el código sea fácil de entender y mantener.

19.4) Usar return para devolver resultados

Hasta ahora, nuestras funciones han realizado acciones (como imprimir), pero no han enviado valores de vuelta al código que las llamó. La sentencia return permite que una función calcule un resultado y lo envíe de vuelta al llamador.

Sentencia return básica

Aquí tienes una función simple que calcula y devuelve un valor:

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

Output:

The sum is: 8

Cuando Python encuentra una sentencia return, ocurren dos cosas:

  1. La función deja de ejecutarse inmediatamente (se ignora cualquier código después de return)
  2. El valor especificado se envía de vuelta al llamador

Devolver valores directamente

No necesitas guardar el resultado en una variable antes de devolverlo. Puedes devolver una expresión directamente:

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

Output:

4 × 7 = 28

Esto es más conciso y es el estilo preferido para cálculos simples.

Usar valores devueltos

Una vez que una función devuelve un valor, puedes usar ese valor en cualquier lugar donde usarías cualquier otro 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)
 
# Usa el valor devuelto en 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 sale de la función inmediatamente

Cuando Python ejecuta una sentencia return, la función se detiene de inmediato. Cualquier código después del return nunca se ejecuta:

python
def check_age(age):
    if age < 18:
        return "Minor"
    # Esta línea solo se ejecuta si age >= 18
    return "Adult"
 
print(check_age(15))
print(check_age(25))

Output:

Minor
Adult

Este comportamiento es útil para manejar diferentes casos en una función. Una vez que has determinado el resultado, puedes devolverlo inmediatamente sin necesidad de comprobar condiciones adicionales.

Aquí tienes un ejemplo que demuestra cómo return detiene la ejecución:

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

Funciones sin return

Si una función no tiene una sentencia return, o si tiene un return sin valor, la función devuelve None:

python
def greet(name):
    print(f"Hello, {name}!")
    # Sin sentencia return
 
result = greet("Alice")
print(f"The function returned: {result}")

Output:

Hello, Alice!
The function returned: None

De manera similar, un return vacío (sin valor) también devuelve None:

python
def process_data(data):
    if not data:
        return  # Salida temprana, devuelve 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

Devolver múltiples valores

Las funciones de Python pueden devolver múltiples valores separándolos con comas. Python los empaqueta automáticamente en una tupla (como aprendimos en el Capítulo 15):

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

Output:

Area: 15
Perimeter: 16

También puedes capturar la tupla como un solo valor:

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

Output:

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

Devolver distintos tipos

Una función puede devolver tipos diferentes de valores dependiendo de la situación:

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

Aunque esto funciona, por lo general es una mejor práctica manejar los errores de otra manera (aprenderemos sobre excepciones en la Parte VII). Por ahora, entiende que las funciones pueden devolver diferentes tipos, aunque a menudo es más claro ser consistente.

19.5) Documentar funciones con docstrings

A medida que tus programas crecen y creas más funciones, se vuelve crucial documentar qué hace cada función. Python proporciona una forma integrada de documentar funciones usando docstrings (cadenas de documentación).

¿Qué es un docstring?

Un docstring es un literal de cadena que aparece como la primera sentencia en una función (o módulo, clase o método). Describe qué hace la función, qué parámetros acepta y qué devuelve. Los docstrings se encierran entre comillas triples (""" o '''), lo que les permite abarcar múltiples líneas.

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 qué importan los docstrings

Los docstrings cumplen varios propósitos importantes:

  1. Autodocumentación: Explican qué hace tu función sin requerir que los lectores analicen el código
  2. Soporte del IDE: Muchas herramientas de desarrollo muestran los docstrings como tooltips cuando usas una función
  3. Función help(): La función integrada help() de Python muestra docstrings
  4. Práctica profesional: Un código bien documentado es más fácil de mantener y compartir con otros

Formato básico de docstring

Para funciones simples, un docstring de una línea es suficiente:

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

Output:

Print a personalized greeting.

El docstring debería ser una descripción concisa de lo que hace la función, escrita como un mandato ("Calculate...", "Return...", "Print...") en lugar de una descripción ("This function calculates...").

Docstrings de varias líneas

Para funciones más complejas, usa docstrings de varias líneas que incluyan:

  • Un resumen breve en la primera línea
  • Una línea en blanco
  • Una descripción más detallada
  • Información sobre parámetros
  • Información 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)
 
# Usa help() para ver el docstring completo
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

Convenciones de docstring

Python tiene convenciones establecidas para escribir docstrings (documentadas en PEP 257). Aquí están las pautas clave:

1. Usa comillas dobles triples: """docstring"""

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

2. Los docstrings de una línea deberían caber en una línea:

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

3. Los docstrings de varias líneas deberían tener una línea de resumen y luego una línea en blanco:

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'
    """
    # Implementación de la función aquí
    pass

Describir parámetros y valores de retorno

Al documentar parámetros y valores de retorno, sé específico sobre:

  • Nombres de parámetros: Que coincidan con los nombres reales de los parámetros en la función
  • Tipos: Qué tipo de dato se espera (aprenderemos sobre type hints en el Capítulo 43)
  • Propósito: Para qué se usa el parámetro
  • Valor de retorno: Qué devuelve la función y bajo qué condiciones
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 funciones con múltiples tipos de retorno

Cuando una función puede devolver distintos tipos dependiendo de la situación, documenta todas las posibilidades:

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

Acceder a docstrings

Puedes acceder al docstring de una función de tres maneras:

1. Usando el atributo __doc__:

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

Output:

This is an example function.

2. Usando la función 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. En entornos de desarrollo interactivos: La mayoría de los IDEs y editores de código muestran docstrings como tooltips cuando pasas el cursor sobre, o escribes, el nombre de una función.

Cuándo escribir docstrings

Deberías escribir docstrings para:

  • Todas las funciones públicas: Funciones que están pensadas para ser usadas por otras partes de tu programa o por otros programadores
  • Funciones complejas: Cualquier función cuyo propósito o comportamiento no sea inmediatamente obvio por su nombre y parámetros
  • Funciones con parámetros no obvios: Cuando los nombres de los parámetros por sí solos no explican completamente qué valores se esperan

Podrías omitir docstrings para:

  • Funciones muy simples y obvias: Funciones como def add(a, b): return a + b donde el nombre y los parámetros dejan el propósito totalmente claro
  • Funciones auxiliares privadas: Funciones internas pequeñas usadas solo dentro de una función mayor (aunque incluso estas se benefician de docstrings breves)

Los docstrings no son comentarios

Recuerda que los docstrings cumplen un propósito diferente al de los comentarios:

  • Docstrings: Describen qué hace una función y cómo usarla (la interfaz)
  • Comentarios: Explican cómo funciona el código internamente (la implementación)
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)
    """
    # Evitar división por cero
    if total == 0:
        return 0.0
    
    # Calcular el porcentaje y redondear a 2 decimales
    percentage = (score / total) * 100
    return round(percentage, 2)

El docstring le dice a los usuarios qué hace la función y cómo usarla. Los comentarios explican detalles específicos de la implementación a alguien que esté leyendo el código.

Construir buenos hábitos de documentación

Escribir docstrings claros es un hábito que rinde frutos:

  • Escribe docstrings mientras escribes funciones: No esperes hasta después—documenta mientras el propósito de la función está fresco en tu mente
  • Mantén los docstrings actualizados: Cuando cambies el comportamiento de una función, actualiza su docstring
  • Sé conciso pero completo: Incluye toda la información necesaria, pero evita la verbosidad innecesaria
  • Usa ejemplos cuando sea útil: Para funciones complejas, un ejemplo de uso en el docstring puede ser invaluable

Una buena documentación hace que tu código sea más profesional, más fácil de mantener y más valioso para otros (incluyéndote a ti en el futuro).

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