Las funciones en Python admiten parámetros dinámicos para capturar un número variable de argumentos. Los parámetros posicionales adicionales se recolectan en una tupla usando *args (convención común), y los parámetros de palabra clave adicionales en un diccionario con **kwargs.
def calcular_suma(*valores):
print("Total:", sum(valores))
print("Tupla de argumentos:", valores)
calcular_suma(2, 4, 6)
# Salida:
# Total: 12
# Tupla de argumentos: (2, 4, 6)
La jerarquía de parámetros es: posicionales > posicionales dinámicos > con valor por defecto > de palabra clave dinámicos.
def ajustar_configuracion(base, *extras, por_defecto=10, **opciones):
print(base, extras, por_defecto, opciones)
ajustar_configuracion("inicio", "suplemento1", "suplemento2", por_defecto=7, tema="oscuro")
# Salida:
# inicio ('suplemento1', 'suplemento2') 7 {'tema': 'oscuro'}
Para aceptar cualquier combinación de argumentos, se puede usar *args y **kwargs en una función "general".
def funcion_general(*args, **kwargs):
print("Posicionales:", args)
print("Palabra clave:", kwargs)
funcion_general(1, 2, x=3, y=4)
# Salida:
# Posicionales: (1, 2)
# Palabra clave: {'x': 3, 'y': 4}
El operador * desempaqueta secuencias al invocar funciones.
lista_numeros = [10, 20, 30]
calcular_suma(*lista_numeros)
Las anotaciones de funciones se usan para documentación y proporcionan metainforamción. Se escriben mediante docstrings o anotaciones de tipo, que no imponen restricciones en tiempo de ejecución.
def dividir(dividendo, divisor):
"""
Divide dos números.
:param dividendo: Número a dividir.
:param divisor: Número divisor.
:return: Resultado de la división.
"""
return dividendo / divisor
print(dividir.__doc__)
def concatenar(a: str, b: str) -> str:
return a + b
print(concatenar("hola", "mundo")) # Salida: holamundo
print(concatenar(1, 2)) # Salida: 12, sin error en runtime
Los espacios de nombres gestionan el ámbito de las variables: integrado (built-in), global y local. El orden de carga es integrado > global > local, y el orden de búsqueda de valores es local > global > integrado.
Las funciones globals() y locals() inspeccionan estos espacios.
variable_global = "global"
def ejemplo_ambito():
variable_local = "local"
print("Espacio local:", locals())
print("Espacio global:", globals())
ejemplo_ambito()
El ámbito global incluye los integrado y global, accedible con globals(). El ámbito local es específico de la función, accedible con locals().
En Python, las funciones son objetos de primera clase: pueden asignarse a variables, pasarse como argumentos, retornarse de otras funciones o almacenarse en contenedores.
def mostrar_mensaje():
print("Mensaje importante")
referencia_funcion = mostrar_mensaje
referencia_funcion() # Salida: Mensaje importante
def ejecutar_funcion(func):
func()
ejecutar_funcion(mostrar_mensaje) # Salida: Mensaje importante
def crear_multiplicador(factor):
def multiplicar(x):
return x * factor
return multiplicar
triple = crear_multiplicador(3)
print(triple(5)) # Salida: 15
diccionario_acciones = {
"accion1": lambda x: x ** 2,
"accion2": lambda x: x + 10,
}
print(diccionario_acciones["accion1"](4)) # Salida: 16
La anidación de funciones permite definir funciones dentro de otras, creando jerarquías de ámbito.
def funcion_externa():
contador = 0
def funcion_interna():
contador_interno = 5
print("Interno:", contador + contador_interno)
funcion_interna()
funcion_externa() # Salida: Interno: 5
La palabra clave global permite modifciar una varible global desde una función local.
acumulador = 0
def incrementar_acumulador():
global acumulador
acumulador += 1
incrementar_acumulador()
print(acumulador) # Salida: 1
Para tipos mutables como diccionarios, se puede modificar el contenido sin usar global.
perfil = {"nombre": "Carlos"}
def actualizar_nombre():
perfil["nombre"] = "Luis"
actualizar_nombre()
print(perfil) # Salida: {'nombre': 'Luis'}
La palabra clave nonlocal modifica una variable en el ámbito local de una función contenedora inmediata, no la global.
def nivel_a():
valor = 10
def nivel_b():
valor_b = 5
def nivel_c():
nonlocal valor_b
valor_b += 2
print("Valor modificado:", valor_b)
nivel_c()
nivel_b()
nivel_a() # Salida: Valor modificado: 7