Funciones con Python

Las funciones con Python son bloques de código identificados por un nombre y que únicamente se ejecutan cuando son llamadas. Las funciones se definen con la palabra clave def, seguida de un nombre() y dos puntos. Se les pueden pasar datos de diferentes tipos entre paréntesis después del nombre → parámetros y también puede retornar datos → resultado.

Función en Python

def nombre_funcion(parametros):
    bloque de codigo
    return resultado

Veamos un ejemplo muy sencillo de una función en Python:

def saludo():
    print('Hola mundo!')

La función saludo() que hemos creado no hace nada si no la llamamos; se queda a la espera para ejecutar el bloque de código que contiene hasta que la llamemos.

¿Cómo llamamos a la función saludo()? A las funciones en Python se las llama por su nombre seguido de apertura y cierre de paréntesis.

La guía de estilos PEP8 recomienda dejar siempre dos líneas en blanco antes y después de escribir funciones en Python. Puedes leer algo más sobre las recomendaciones de PEP8 para las funciones en Python.

def saludo():
    print('Hola mundo!')


saludo()

# Hola mundo!

La función saludo() no devuelve ningún resultado, únicamente imprime en consola Hola mundo! cuando la llamamos. Podemos llamar a una función tantas veces como sea necesaria.

Retornando un valor desde la función

Veamos ahora un ejemplo de función en Python que realice una operación matemática:

Realizaremos una suma para que nos devuelva el resultado de esta. Este resultado lo vamos a guardar en una variable y la imprimiremos en pantalla mediante una f string de Python.

def suma():
    resultado = 5 + 10
    return resultado


variable = suma()
print(f'Este es el resultado → {variable}')

# Este es el resultado → 15

Hasta ahora las dos funciones que hemos creado realizan alguna acción en su bloque de código, pero siempre es fija. La función saludo siempre dice Hola mundo!, y la de suma siempre va a devolvernos el resultado de sumar 5 + 10.

Parámetros y argumentos en la función

Los parámetros y argumentos nos van a permitir poder llamar a la función y al mismo tiempo enviarle datos para que el bloque de código que se ejecuta en su interior los tenga en cuenta. Para poder realizar esto, tenemos que definir nuestra función indicando qué parámetros van a ser enviados cuando se llame a la función.

En la función se definen los parámetros necesarios. Al llamarla nosotros debemos enviarle los argumentos.

En el ejemplo vamos a definir la función para que reciba como parámetro un nombre. Cuando la llamemos, le enviaremos un nombre como argumento; así, podrá saludar al nombre que le indiquemos.

def saludo(un_nombre):
    print(f'Hola {un_nombre}!')


saludo('Luis')
# Hola Luis!

saludo('El nombre que quieras')
# Hola El nombre que quieras

Ahora vamos a enviar también argumentos a la función suma() que hemos creado anteriormente. Enviaremos dos números para que se sumen y nos devuelva el resultado. Cuando se envía más de un argumento a la función, estos se tienen que separar mediante comas.

No podemos enviar un número de argumentos distinto al número de parámetros que se hayan definido al crear la función.

def suma(a, b):
    resultado = a + b
    return resultado


variable = suma(20, 50)
print(f'Este es el resultado → {variable}')
# Este es el resultado → 70

variable_dos = suma(10, 10)
print(f'Este es el resultado → {variable}')
# Este es el resultado → 20

Si lo necesitásemos, podríamos sumar dos números llamando a la función suma(numero1, numero2) e indicándole como argumentos los dos valores que necesitamos sumar.

Tipos de argumento al pasar datos

Los argumentos se los podemos pasar a las funciones de dos formas:

  • De forma posicional
  • De forma nominal

Para ver la diferencia pasando datos mediante argumentos en una función de Python, vamos a crear una función que reste dos números.

Primero realizaremos un pase de argumentos por posición.

def resta(a, b):
    return a - b


print(f'Resultado → {resta(10, 2)}')
# Resultado → 8

Ahora vamos a hacer el mismo ejemplo, pero realizando un pase de argumentos de forma nominal. Vamos a ver que el resultado es exactamente el mismo: la resta de 10 menos 2 es igual a 8.

def resta(a, b):
    return a - b


print(f'Resultado → {resta(a=10, b=2)}')
# Resultado → 8

¿Qué pasaría si cambiásemos la posición de los argumentos en el pase por posición? Veámoslo con un ejemplo:

def resta(a, b):
    return a - b


print(f'Resultado → {resta(2, 10)}')
# Resultado → -8

El resultado pasa a ser -8

¿Qué pasaría si cambiásemos la posición de los parámetros cuando los pasamos de forma nominal?

def resta(a, b):
    return a - b


print(f'Resultado → {resta(b=2, a=10)}')
# Resultado → 8

No pasaría nada, ya que a sigue valiendo 10 y b sigue valiendo 2, independientemente de la posición que ocupen como argumentos al llamar a la función.

Parámetros opcionales en una función

Existe la posibilidad de incluir parámetros opcionales en nuestra función. Para hacer uso de parámetros por defecto, es necesario definir nuestra función con parámetros que incluyan valores por defecto.

Vamos a ver un ejemplo con una función de suma:

Esta función debería recibir los valores a y b. Si no los recibe cuando se llama, muestra el siguiente error.

def suma(a, b):
    return a + b


print(suma())
# TypeError: suma() missing 2 required positional arguments: 'a' and 'b'

Ahora definiremos esta misma función, pero haciendo opcionales los dos parámetros. Para ello, le asignaremos el valor 0 por defecto mientras creamos la función.

def suma(a=0, b=0):
    return a + b


print(suma())
# 0

Número de argumentos indeterminados

Python también nos ofrece la posibilidad de enviar un número indeterminado de argumentos a nuestra función. Anteriormente hemos visto que al crear nuestra función es necesario conocer el número de argumentos que va a recibir esta para definir los parámetros.

Entonces, ¿cómo es posible ahora enviar un número indeterminado de argumentos? Sí. Declarando nuestro parámetro en la función con un asterisco * delante, transformará nuestro parámetro en una tupla de Python.

Vamos a verlo con un ejemplo en el que enviaremos un número indeterminado de días a nuestra función:

El parámetro (*dias) transformará en una tupla los valores que le enviemos cuando llamemos a la función. Estos valores los recorreremos mediante la estructura for de Python para mostrar los datos.

Podemos ver en este primer ejemplo que, inmediatamente después de entrar en el bloque de nuestra función, el parámetro dias ya es de tipo tupla. No es obligatorio enviar ningún número de parámetros.

def muestro_dias(*dias):
    print(type(dias))


muestro_dias()
# <class 'tuple'>

Veamos ahora un ejemplo en el que se han enviado tres días de la semana.

def muestro_dias(*dias):
    for dia in dias:
        print(dia)


muestro_dias('Lunes', 'Martes', 'Miércoles')
# Lunes
# Martes
# Miércoles

Vamos a ver un ejemplo de máquina de sumar en el que se ha enviado un número indeterminado de argumentos. Para el ejemplo, enviaremos cinco valores, pero esta función de Python está creada mediante *numeros, por lo cual admite que se le envíe un número indeterminado de argumentos.

def sumo_numeros(*numeros):
    total = 0
    for numero in numeros:
        total = total + numero
    return total


resultado = sumo_numeros(10, 22, 43, 41, 100)
print(f'El total es → {resultado}')

# El total es → 216

Envío de clave y valor como argumento

Podemos utilizar el doble asterisco ** al definir los parámetros de nuestra función. De esta forma le estaremos indicando que el argumento que nos van a enviar es del tipo clave: valor.

Veamos cómo se transforma en un diccionario de Python nuestro parámetro dias dentro de la función en cuanto es llamada.

def muestro_dias(**dias):
    print(type(dias))


muestro_dias()
# <class 'dict'>

Para entender este ejemplo, deberíamos saber que existen tres métodos para trabajar con los diccionarios de Python y tener acceso a las claves y valores que contiene. Nosotros utilizaremos items() para que nos devuelva valor: clave.

def muestro_dias(**kwargs):
    for clave, valor in kwargs.items():
        print(f'{clave} → {valor}')


semana = {
    'Lunes': 'laboral', 
    'Martes': 'festivo', 
    'Miércoles': 'laboral', 
    'Jueves': 'laboral', 
    'Viernes': 'festivo', 
    'Sábado': 'festivo', 
    'Domingo': 'festivo'
}
muestro_dias(**semana)

# Lunes → laboral
# Martes → festivo
# Miércoles → laboral
# Jueves → laboral
# Viernes → festivo
# Sábado → festivo
# Domingo → festivo

Aunque por convención se utiliza kwargs cuando utilizamos el doble asterisco **kwargs, podríamos llamar al parámetro del ejemplo anterior **dias y también funcionaría correctamente.

Sentencia return para las funciones

Con la sentencia return dentro de nuestra función, estamos indicando que hemos terminado de realizar operaciones en nuestro bloque de código. Podemos salir del bloque de código de nuestra función con return retornando uno o varios valores, siendo este valor el resultado de las operaciones que hemos estado realizando en la función.

Veámoslo con un ejemplo sencillo:

Crearemos una función que realice algunas operaciones aritméticas y retornaremos el resultado.

def realiza_operaciones(a, b):
    resultado = a + b
    resultado = (resultado * 100) / 4
    return resultado


realiza_operaciones(1, 2)
# 75.0

Ahora vamos a crear otra función que realice también operaciones aritméticas, pero esta vez devolverá dos valores; por un lado, el resultado de la suma inicial y, por otro, el resultado final.

def realiza_operaciones(a, b):
    resultado_suma = a + b
    resultado = (resultado_suma * 100) / 4
    return resultado_suma, resultado


v_suma, v_resul = realiza_operaciones(1, 2)

print(v_suma)
# 3

print(v_resul)
# 75.0

Aunque se nos puede pasar por la cabeza retornar dos veces, esta idea tenemos que desecharla de inmediato. No podemos retornar varias veces: una vez que estamos ejecutando el código de nuestra función y se retorna un valor, automáticamente salimos de la función y la siguiente línea no se ejecutará.

En este ejemplo únicamente se realiza la suma de a más b; una vez que retornamos resultado_suma salimos de la función.

def realiza_operaciones(a, b):
    resultado_suma = a + b
    return resultado_suma
    resultado = (resultado_suma * 100) / 4
    return resultado_suma, resultado


realiza_operaciones(1, 2)
# 3

Es posible llamar a una función y que esta no realice ninguna operación, que simplemente sirva para devolver un valor.

def saludar():
    return 'Buenos días'


print(saludar())
# Buenos días

Documentar funciones en Python

La mayoría de las funciones que creamos deberían ser documentadas mientras estamos escribiéndolas, ya que es posible que, pasado un tiempo, necesitemos recordar su funcionamiento. Si contamos con la documentación, no tendremos que analizar de nuevo el código línea a línea.

La forma de documentar una función es muy sencilla. La vamos a ver con un ejemplo documentando una función que sirve para sumar.

Debemos escribir en la primera línea de nuestra función un comentario con triple comilla en el que especificaremos la información que pensamos que será necesaria conocer en el futuro para conocer el funcionamiento de nuestra función.

def suma(a, b):
    '''
    Esta función recibe dos argumentos que son sumados y devuelve el valor de la suma en un f string.
    '''
    return f'Resultado: {a + b}'

En este ejemplo estamos documentando nuestra función de suma. Aunque en una función tan simple quizás no tenga sentido documentarla, es una práctica que debemos incorporar lo antes posible cuando escribimos funciones. Si algún día decidiésemos compartir nuestras funciones con alguien que no esté familiarizado con nuestra forma de escribir código, disponer de documentación en nuestras funciones le facilitará muchísimo su uso.

Para ver la documentación de las funciones podemos hacerlo de dos formas:

  • print(help(mi_funcion))
  • print(mi_funcion.__doc__)
def suma(a, b):
    '''
    Esta función recibe dos argumentos que son sumados y devuelve el valor de la suma en un f string.
    '''
    return f'Resultado: {a + b}'


print(help(suma))
# Help on function suma in module __main__:

# suma(a, b)
#     Esta función recibe dos argumentos que 
# son sumados y devuelve el valor de la suma en # un f string.

print(suma.__doc__)
# Esta función recibe dos argumentos que son 
# sumados y devuelve el valor de la suma en un # f string.

Vamos a dejar las funciones recursivas y las funciones lambda para entradas separadas. Desde este enlace puedes ver todo lo relacionado con las funciones en la documentación oficial de Python.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *