Funciones en Python. En este capítulo nos adentraremos en uno de los conceptos más importantes de la programación: las funciones. Las funciones permiten dividir un programa en partes más pequeñas y manejables, facilitando la reutilización del código y la mejora en la legibilidad. Aprenderemos cómo definir nuestras propias funciones, cómo trabajar con argumentos y parámetros, y cómo asignar valores por defecto.
También exploraremos el poder de las funciones lambda, que son funciones anónimas y rápidas para realizar tareas sencillas en una sola línea de código. Otro concepto clave será el alcance de las variables, es decir, la diferencia entre variables locales y globales, lo cual es fundamental para controlar cómo y dónde pueden ser accedidas las variables dentro de un programa.
Finalmente veremos una introducción a los decoradores, una herramienta poderosa para modificar el comportamiento de una función sin alterar su código. Este capítulo te proporcionará la base para entender y escribir funciones en Python, ayudando a estructurar tus programas de manera más eficiente y modular.
Sin mas dilación comencemos con la lección.
Definición de una Función en Python
En Python, las funciones son bloques de código reutilizables que permiten organizar tareas específicas en un programa. Una función puede realizar una tarea, recibir datos, devolver resultados, o simplemente ser usada para estructurar un programa de manera más limpia.
Sintaxis básica de una función:
La sintaxis de una función en Python se define con la palabra clave def
, seguida del nombre de la función y paréntesis ()
que pueden o no contener parámetros. El cuerpo de la función se encuentra dentro de un bloque indentado.
def nombre_de_la_funcion(parametros):
# Bloque de código que realiza alguna tarea
return valor # (opcional)
- Nombre de la función: Debe seguir las reglas de nomenclatura de Python (letras, números, guiones bajos, sin espacios y no puede empezar con un número).
- Parámetros: Opcionales, permiten que la función reciba datos. Estos datos se pueden usar dentro de la función.
- Return: La palabra clave
return
es opcional y se usa para devolver un valor de la función al lugar donde fue llamada.
Ejemplo de una función básica:
def saludar():
print("¡Hola, Mundo!")
saludar() # Llamada a la función saludar() para ejecutarla.
- En este ejemplo, la función
saludar
no toma parámetros y simplemente imprime un mensaje en pantalla cuando es llamada.
Funciones con Parámetros
Los parámetros permiten a las funciones recibir valores externos cuando son llamadas. Estos valores son utilizados dentro del bloque de código de la función para realizar tareas específicas.
Ejemplo de una función con parámetros:
def saludar_persona(nombre):
print(f"¡Hola, {nombre}!")
saludar_persona("Ana") # Llamada a la función con el argumento "Ana"
- Aquí,
nombre
es un parámetro de la función. - Cuando llamamos a
saludar_persona("Ana")
, pasamos el argumento"Ana"
a la función que lo utiliza dentro del bloque de código para personalizar el saludo.
Retorno de Valores
Una función puede devolver un valor al lugar donde fue llamada mediante el uso de la palabra clave return
. Esto es útil cuando queremos que la función realice algún cálculo o procesamiento y nos devuelva el resultado.
Ejemplo de función con retorno de valores:
def suma(a, b):
return a + b
resultado = suma(3, 5)
print(resultado) # Salida: 8
- La función
suma
toma dos parámetrosa
yb
, los suma y devuelve el resultado usandoreturn
. - El valor devuelto se asigna a la variable
resultado
que luego se imprime por pantalla.
Argumentos y parámetros
Los parámetros son los nombres que aparecen en la definición de la función, y los argumentos son los valores reales que se pasan cuando se llama a la función.
Tipos de parámetros:
- Argumentos Posicionales:
Estos se pasan a la función en el mismo orden en que aparecen los parámetros en la definición de la función.
def multiplicar(a, b):
return a * b
resultado = multiplicar(2, 3) # Llamada con argumentos posicionales
2. Parámetros con nombre (keyword arguments):
Puedes llamar a una función utilizando el nombre de los parámetros, lo que permite especificar los argumentos en cualquier orden.
def persona(nombre, edad):
print(f"{nombre} tiene {edad} años")
persona(edad=25, nombre="Carlos") # Llamada con argumentos con nombre
- En este ejemplo hemos pasado los argumentos
nombre
yedad
usando sus nombres, lo que facilita la legibilidad del código y permite especificar los argumentos en cualquier orden.
Valor por defecto de parámetros
Puedes asignar valores por defecto a los parámetros de una función. Si no se pasa un argumento para ese parámetro, se usará el valor por defecto. Si se pasa un argumento, este sobrescribirá el valor por defecto.
Ejemplo:
def saludar_persona(nombre="Desconocido"):
print(f"¡Hola, {nombre}!")
saludar_persona() # Llamada sin argumento, usa el valor por defecto. Imprimirá "¡Hola Desconocido!"
saludar_persona("Ana") # Llamada con argumento, sobrescribe el valor por defecto. Imprimirá "¡Hola Ana!"
- Si no se pasa ningún argumento, se usa el valor por defecto
"Desconocido"
. - Si se pasa un argumento (en este caso
"Ana"
), este sobrescribe el valor por defecto.
¿Qué tipos de parámetros que se pueden pasar a una función?
Las funciones pueden recibir como parámetro una amplia variedad de tipos de datos. Esto se debe a que Python es un lenguaje dinámicamente tipado, lo que significa que no es necesario declarar el tipo de dato de un parámetro cuando se define una función. A continuación, se detallan los tipos de datos más comunes que puede recibir una función en Python:
Tipos de datos básicos
Estos son los tipos de datos fundamentales que puedes pasar como parámetros a una función.
- Enteros (
int
): Números enteros, positivos o negativos.
def sumar(a, b):
return a + b
resultado = sumar(5, 3) # a y b son enteros
- Flotantes (
float
): Números con decimales.
def area_circulo(radio):
return 3.1416 * radio ** 2
area = area_circulo(2.5) # radio es un flotante
- Cadenas de texto (
str
): Secuencias de caracteres.
def saludar(nombre):
print(f"Hola, {nombre}!")
saludar("Carlos") # nombre es una cadena
- Booleanos (
bool
): Valores lógicosTrue
oFalse
.
def imprime_valor(valor):
if valor:
print("Valor es Verdadero")
else:
print("Valor es Falso")
imprimer_valor(True)
Colecciones
Las funciones también pueden recibir estructuras de datos más complejas, como listas, tuplas, conjuntos, o diccionarios.
- Listas (
list
): Colecciones de elementos ordenados y mutables.
def imprimir_lista(lista):
for elemento in lista:
print(elemento)
imprimir_lista([1, 2, 3, 4]) # Imprime la lista de enteros
- Tuplas (
tuple
): Colecciones de elementos ordenados pero inmutables.
def procesar_tupla(tupla):
return tupla[0], tupla[-1]
resultado = procesar_tupla((10, 20, 30)) # Devuelve una tupla de dos elementos
- Conjuntos (
set
): Colecciones de elementos no ordenados y sin duplicados.
def elementos_unicos(conjunto):
return len(conjunto)
resultado = elementos_unicos({1, 2, 2, 3}) # conjunto es un set
- Diccionarios (
dict
): Colecciones de pares clave-valor.
def imprimir_datos_persona(persona):
for clave, valor in persona.items():
print(f"{clave}: {valor}")
imprimir_datos_persona({"nombre": "Ana", "edad": 30}) # persona es un diccionario
Otros tipos de datos
Python permite pasar muchos otros tipos de datos más avanzados como pueden ser:
- Funciones: Puedes pasar una función como parámetro a otra función.
def aplicar_funcion(funcion, valor):
return funcion(valor)
def cuadrado(x):
return x * x
resultado = aplicar_funcion(cuadrado, 5) # cuadrado es una función
- Objetos (de clases definidas por el usuario): Puedes pasar instancias de clases personalizadas como parámetros.
class Persona:
def __init__(self, nombre, edad):
self.nombre = nombre
self.edad = edad
def imprimir_persona(persona):
print(f"Nombre: {persona.nombre}, Edad: {persona.edad}")
p = Persona("Carlos", 25)
imprimir_persona(p) # p es un objeto de la clase Persona
- Ninguno (
None
): El valorNone
también se puede pasar como parámetro para indicar la ausencia de un valor.
def verificar_valor(valor):
if valor is None:
print("No se recibió valor")
else:
print(f"Valor recibido: {valor}")
verificar_valor(None) # valor es None
Argumentos de tipo «iterable» y «callable»
En Python, los iterables (como listas, cadenas, tuplas) y los callables (como funciones o clases con el método __call__
) también se pueden pasar como argumentos.
- Iterables: Cualquier objeto sobre el que se puede iterar, como listas, tuplas o generadores.
def imprimir_iterable(iterable):
for item in iterable:
print(item)
imprimir_iterable([1, 2, 3]) # lista como iterable
imprimir_iterable("abc") # cadena como iterable
- Callables: Cualquier objeto que pueda ser llamado como una función (incluyendo las propias funciones o clases).
def llamar_funcion(funcion):
funcion()
def saludo():
print("¡Hola!")
llamar_funcion(saludo) # saludo es una función (callable)
Parámetros con valores por defecto y argumentos arbitrarios
- Valores por defecto: Puedes definir parámetros con valores por defecto para que la función los utilice en caso de que no se proporcionen argumentos.
def saludar(nombre="Desconocido"):
print(f"Hola, {nombre}")
saludar() # Usará "Desconocido" como valor por defecto
saludar("Carlos") # Usará "Carlos" como argumento
- Argumentos arbitrarios (
*args
y**kwargs
): Puedes definir funciones que acepten un número variable de argumentos posicionales o de palabras clave.
def sumar(*args):
return sum(args)
resultado = sumar(1, 2, 3, 4) # args será (1, 2, 3, 4)
def mostrar_datos(**kwargs):
for clave, valor in kwargs.items():
print(f"{clave}: {valor}")
mostrar_datos(nombre="Carlos", edad=25) # kwargs será {'nombre': 'Carlos', 'edad': 25}
Como has podido apreciar, las funciones en Python pueden recibir cualquier tipo de dato, desde tipos básicos como enteros y cadenas, hasta colecciones complejas como listas y diccionarios, e incluso funciones y objetos. La flexibilidad de Python permite que cualquier tipo de dato, incluido el valor None
, se pueda utilizar como argumento. Esta versatilidad es una de las características que hacen de Python un lenguaje tan potente y fácil de usar.
¿Qué tipo de datos pueden devolver las fuciones?
Seguro que ya te estarás pensando… ¿Si una función puede recibir enteros, flotantes, strings, listas, etc., podrá también devolver estos mismo tipos de datos?
Efectivamente, Las funciones en Python pueden devolver cualquier tipo de dato, desde los tipos más simples como enteros o cadenas de texto, hasta estructuras de datos más complejas como listas, diccionarios o incluso otras funciones. Al igual que con los parámetros de entrada, Python permite una gran flexibilidad en los valores que pueden ser retornados por una función. Simplemente tendremos que poner la variable del tipo de dato que queramos devolver dentro de los paréntesis de la sentencia return().
- Veamos unos ejemplos:
def saludar(nombre="Desconocido"):
return(f"Hola, {nombre}") # devuelve una cadena de caracteres.
def suma(a,b):
return (a+b) # devuelve un entero
def mayor_edad(edad):
return(edad>=18) # Devuelve un bool (True si edad es mayor o igual a 18)
saludo=saludar("Juan) # Almacena en la variable saludo "Hola Juan!"
suma=sumar(3,5) # Almacena en la variable suma 8
es_mayor=mayor_edad(12) # Almacena en la variable es_mayor False
Funciones lambda
Las funciones lambda
son funciones anónimas y de una sola línea, usadas comúnmente cuando se necesita una función rápida y simple. Se crean usando la palabra clave lambda
y no requieren un nombre o la palabra clave def
.
Sintaxis básica:
lambda argumentos: expresión
Ejemplo:
# Función lambda para sumar dos números
suma = lambda a, b: a + b
print(suma(2, 3)) # Salida: 5
Las funciones lambda se suelen utilizar cuando se necesitan pasar funciones como argumentos a otras funciones, como en map()
, filter()
, o sorted()
.
Ejemplo con sorted()
:
lista = [(1, 'uno'), (2, 'dos'), (3, 'tres')]
lista_ordenada = sorted(lista, key=lambda x: x[1])
print(lista_ordenada) # Ordena por la segunda posición: [('dos'), ('tres'), ('uno')]
Alcance de variables (global, local)
El alcance de una variable se refiere a dónde es accesible dentro del código. Hay dos tipos principales de alcance:
- Variables locales: Son aquellas definidas dentro de una función. Solo existen dentro de esa función y no son accesibles fuera de ella.
- Variables globales: Son aquellas definidas fuera de cualquier función y pueden ser accesibles tanto dentro como fuera de las funciones.
Ejemplo de alcance:
x = 10 # Variable global
def mi_funcion():
x = 5 # Variable local, solo existe dentro de la función
print(x)
mi_funcion() # Salida: 5 (imprime la variable local)
print(x) # Salida: 10 (imprime la variable global)
- Dentro de la función,
x
es local, pero fuera de la función,x
hace referencia a la variable global.
Variables globales:
Son aquellas que se definen fuera de cualquier función y están disponibles en todo el programa.
x = 10 # Variable global
def funcion():
print(x)
funcion() # Salida: 10
Modificar variables globales dentro de una función:
Si necesitas modificar una variable global dentro de una función, puedes usar la palabra clave global
.
x = 10
def modificar():
global x
x = 20
modificar()
print(x) # Salida: 20
- En este script se inicia la variable global x a valor 10, pero dentro de la función modificar() hacemos referencia a dicha variable indicando que es global y modificando su valor a 20. Al salir de la función, X continua teniendo el valor 20.
Decoradores
Los decoradores en Python son una manera de modificar o extender el comportamiento de una función o método sin modificar su código fuente. Son funciones que toman otra función como argumento y devuelven una nueva función con comportamiento extendido.
Sintaxis básica:
def decorador(func):
def envoltura():
print("Antes de la función")
func()
print("Después de la función")
return envoltura
Ejemplo:
def decorador(funcion):
def envoltura():
print("Antes de la función")
funcion()
print("Después de la función")
return envoltura
@decorador
def funcion_saludo():
print("¡Hola!")
funcion_saludo() # Llamada a la función decorada
- Aquí,
@decorador
modifica la funciónsaludar
agregando mensajes antes y después de su ejecución. Los decoradores son útiles para agregar funcionalidades a una función sin modificar su definición original.
Decoradores con parámetros:
Si la función que se decora tiene parámetros, el decorador debe aceptarlos y pasarlos correctamente.
def decorador(funcion):
def envoltura(*args, **kwargs):
print("Antes de la función")
resultado = funcion(*args, **kwargs)
print("Después de la función")
return resultado
return envoltura
@decorador
def suma(a, b):
return a + b
print(suma(2, 3)) # Llamada a la función decorada con argumentos
Resumen
Las funciones en Python permiten modularizar el código y mejorar su reutilización. Ya sea creando funciones simples, utilizando argumentos por defecto o decoradores para modificar su comportamiento, las funciones son herramientas clave para escribir programas eficientes. Las funciones lambda y el control del alcance de variables también son esenciales para escribir código claro y manejable.
Te propongo unos ejercicios de funciones para que puedas continuar practicando.
Ejercicio 1: Suma de dos números enteros.
Escribe una función llamada suma
que reciba dos números enteros como parámetros y devuelva su suma.
Escribe una función llamada
suma
que reciba dos números enteros como parámetros y devuelva su suma.# Definimos la función suma que recibe dos parámetros enteros
def suma(a, b):
return a + b # Retornamos la suma de los dos números
# Probamos la función
resultado = suma(5, 7) # Llamamos a la función con 5 y 7 como argumentos
print(resultado) # Salida: 12
Explicación: La función recibe dos enteros, a
y b
, y devuelve su suma utilizando el operador +
.
Ejercicio 2: Verificar si un número es par o impar.
Escribe una función llamada es_par
que reciba un número entero como parámetro y devuelva True
si el número es par, o False
si es impar.
Escribe una función llamada
es_par
que reciba un número entero como parámetro y devuelva True
si el número es par, o False
si es impar.# Definimos la función es_par que recibe un número entero como parámetro
def es_par(numero):
return numero % 2 == 0 # Devuelve True si el número es divisible por 2, es decir, si es par
# Probamos la función
resultado = es_par(10) # Llamamos a la función con el número 10
print(resultado) # Salida: True
Explicación: La función utiliza el operador módulo (%
) para determinar si el número es divisible por 2. Si es divisible, devuelve True
; de lo contrario, devuelve False
.
Ejercicio 3: Concatenar dos cadenas de texto.
Crea una función llamada concatenar
que reciba dos cadenas de texto como parámetros y devuelva una nueva cadena que las una con un espacio entre ellas.
Crea una función llamada
concatenar
que reciba dos cadenas de texto como parámetros y devuelva una nueva cadena que las una con un espacio entre ellas.# Definimos la función concatenar que recibe dos cadenas de texto como parámetros
def concatenar(cadena1, cadena2):
return cadena1 + " " + cadena2 # Concatenamos ambas cadenas con un espacio en medio
# Probamos la función
resultado = concatenar("Hola", "Mundo") # Llamamos a la función con las cadenas "Hola" y "Mundo"
print(resultado) # Salida: "Hola Mundo"
Explicación: La función utiliza el operador +
para concatenar las dos cadenas recibidas y añade un espacio entre ellas.
Ejercicio 4: Crear una lista de cuadrados.
Escribe una función llamada lista_cuadrados
que reciba un número entero positivo como parámetro y devuelva una lista con los cuadrados de los números desde 1 hasta ese número.
Escribe una función llamada
lista_cuadrados
que reciba un número entero positivo como parámetro y devuelva una lista con los cuadrados de los números desde 1 hasta ese número.# Definimos la función lista_cuadrados que recibe un número entero
def lista_cuadrados(n):
# Usamos una comprensión de listas para generar la lista de cuadrados
return [i**2 for i in range(1, n + 1)]
# Probamos la función
resultado = lista_cuadrados(5) # Llamamos a la función con el número 5
print(resultado) # Salida: [1, 4, 9, 16, 25]
Explicación: La función genera una lista de números al cuadrado utilizando una comprensión de listas. La función range(1, n+1)
genera una secuencia de números del 1 al n
, y para cada número se calcula su cuadrado.
Ejercicio 5: Contar las vocales en una cadena.
Escribe una función llamada contar_vocales
que reciba una cadena de texto como parámetro y devuelva un diccionario que indique cuántas veces aparece cada vocal en la cadena.
Escribe una función llamada
contar_vocales
que reciba una cadena de texto como parámetro y devuelva un diccionario que indique cuántas veces aparece cada vocal en la cadena.# Definimos la función contar_vocales que recibe una cadena de texto
def contar_vocales(cadena):
# Inicializamos un diccionario con las vocales en minúscula y en mayúscula
conteo = {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}
# Convertimos la cadena a minúsculas para evitar problemas de mayúsculas
cadena = cadena.lower()
# Recorremos cada carácter de la cadena
for caracter in cadena:
# Si el carácter es una vocal, incrementamos su conteo en el diccionario
if caracter in conteo:
conteo[caracter] += 1
return conteo # Devolvemos el diccionario con el conteo de vocales
# Probamos la función
resultado = contar_vocales("Hola Mundo")
print(resultado) # Salida: {'a': 1, 'e': 0, 'i': 0, 'o': 2, 'u': 1}
Explicación:
- Inicializamos un diccionario con las vocales y establecemos su conteo en 0.
- Convertimos la cadena a minúsculas para uniformar las vocales.
- Recorremos cada carácter y, si es una vocal, aumentamos su conteo en el diccionario.
- La función devuelve el diccionario con el número de apariciones de cada vocal.
Bibliografía de Python de interés.
- Curso de Programación Python. Autor: Arturo Montejo Ráez y Salud María Jiménez Zafra (Editorial Anaya)
- Aprende Python desde cero hasta avanzado. Autor: Xavier Reyes Ochoa (Editorial Book Shelter GmbH)
- Aprende la Programación Orientada a Objetos con el lenguaje Python. Autor: Vincent Boucheny (Editorial Ediciones ENI)
- 100 Ejercicios Python para praticar. Autor: Laurentine K.Masson (Editorial: Publicación Independiente).