Definicion de funciones
Las funciones son los bloques de construccion principales para la reutilizacion de codigo en Python. Definidas con la palabra clave def, encapsulan logica en unidades invocables. Las funciones de Python son objetos de primera clase, lo que significa que pueden asignarse a variables, pasarse como argumentos y devolverse desde otras funciones.
# Basic function definition
def greet(name):
"""Return a greeting message."""
return f"Hello, {name}!"
print(greet("Alice")) # "Hello, Alice!"
# Function with multiple return values (returns a tuple)
def divide(a, b):
quotient = a // b
remainder = a % b
return quotient, remainder
q, r = divide(17, 5)
print(f"17 / 5 = {q} remainder {r}") # 17 / 5 = 3 remainder 2
# Functions without return statement return None
def say_hello(name):
print(f"Hello, {name}!")
result = say_hello("Bob")
print(result) # None
Argumentos de funciones
Python soporta varios tipos de argumentos de funcion: posicionales, con nombre, por defecto, posicionales de longitud variable (*args) y con nombre de longitud variable (**kwargs). Entender estos es esencial para escribir APIs flexibles y limpias.
# Default arguments
def power(base, exponent=2):
return base ** exponent
print(power(3)) # 9 (uses default exponent=2)
print(power(3, 3)) # 27
# Keyword arguments
def create_user(name, age, email=""):
return {"name": name, "age": age, "email": email}
user = create_user(age=30, name="Alice", email="alice@example.com")
# *args - variable positional arguments
def sum_all(*args):
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3, 4, 5)) # 15
# **kwargs - variable keyword arguments
def build_profile(**kwargs):
return kwargs
profile = build_profile(name="Alice", age=30, role="Engineer")
print(profile) # {'name': 'Alice', 'age': 30, 'role': 'Engineer'}
# Combining all argument types
def complex_function(required, *args, default="value", **kwargs):
print(f"Required: {required}")
print(f"Args: {args}")
print(f"Default: {default}")
print(f"Kwargs: {kwargs}")
complex_function("hello", 1, 2, 3, default="custom", extra="data")
# Positional-only and keyword-only arguments (Python 3.8+)
def strict_function(pos_only, /, normal, *, kw_only):
print(pos_only, normal, kw_only)
strict_function(1, 2, kw_only=3) # Works
strict_function(1, normal=2, kw_only=3) # Works
# strict_function(pos_only=1, normal=2, kw_only=3) # Error!
Trampa de argumentos mutables por defecto
Uno de los errores mas comunes en Python es usar un objeto mutable como argumento por defecto. El valor por defecto se crea una vez cuando se define la funcion, no cada vez que se llama.
# BAD - mutable default argument
def add_item_bad(item, items=[]):
items.append(item)
return items
print(add_item_bad("a")) # ['a']
print(add_item_bad("b")) # ['a', 'b'] - Unexpected!
# GOOD - use None as default
def add_item_good(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item_good("a")) # ['a']
print(add_item_good("b")) # ['b'] - Correct!
Funciones lambda
Las funciones lambda son funciones pequenas y anonimas definidas con la palabra clave lambda. Estan limitadas a una sola expresion y se usan comunmente como argumentos para funciones de orden superior como sorted(), map() y filter().
# Lambda syntax
square = lambda x: x ** 2
print(square(5)) # 25
# Lambdas are most useful as arguments
students = [
{"name": "Alice", "grade": 92},
{"name": "Bob", "grade": 85},
{"name": "Charlie", "grade": 98},
]
# Sort by grade
sorted_students = sorted(students, key=lambda s: s["grade"], reverse=True)
print(sorted_students[0]["name"]) # "Charlie"
# map and filter
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squares = list(map(lambda x: x ** 2, numbers))
evens = list(filter(lambda x: x % 2 == 0, numbers))
# Note: list comprehensions are usually preferred over map/filter
squares = [x ** 2 for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
Modulos e importaciones
Un modulo es simplemente un archivo Python. Un paquete es un directorio que contiene un archivo __init__.py. El sistema de importacion de Python te permite organizar el codigo en unidades reutilizables y acceder a la vasta biblioteca estandar y paquetes de terceros.
# Importing modules
import math
print(math.sqrt(16)) # 4.0
print(math.pi) # 3.141592653589793
# Import specific items
from datetime import datetime, timedelta
now = datetime.now()
tomorrow = now + timedelta(days=1)
# Import with alias
import numpy as np
import pandas as pd
# Import everything (avoid in production code)
from math import *
# Creating your own module
# utils.py
def sanitize(text):
return text.strip().lower()
def validate_email(email):
return "@" in email and "." in email
# main.py
# from utils import sanitize, validate_email
Creacion de paquetes
Los paquetes te permiten organizar modulos relacionados en una jerarquia de directorios. Cada directorio de paquete necesita un archivo __init__.py (que puede estar vacio). Este archivo se ejecuta cuando se importa el paquete y puede usarse para definir la API publica del paquete.
# Package structure:
# mypackage/
# __init__.py
# math_utils.py
# string_utils.py
# subpackage/
# __init__.py
# helpers.py
# mypackage/__init__.py
from .math_utils import add, multiply
from .string_utils import capitalize_words
# mypackage/math_utils.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b
# Usage:
# from mypackage import add, multiply
# from mypackage.string_utils import capitalize_words
# from mypackage.subpackage.helpers import some_function
# Relative imports (within a package)
# from . import math_utils # same package
# from .. import other_package # parent package
# from .subpackage import helpers # subpackage
Puntos clave
- Funciones de primera clase: Las funciones pueden pasarse como cualquier otro objeto
- Evita valores mutables por defecto: Usa None en lugar de [] o {} como argumentos por defecto
- *args y **kwargs: Proporcionan flexibilidad para numeros variables de argumentos
- Prefiere comprehensions: Usa list comprehensions sobre map/filter para legibilidad
- Organiza con paquetes: Agrupa modulos relacionados en directorios con __init__.py