Funciones en Python

Por Jose R. Zapata

Ultima actualización: 14/Mar/2025

En este notebook se encuentra los temas mas importantes para el uso de python en ciencia de datos, se debe tener un un conocimiento básico de programación para entender completamente el notebook.

Invítame a un Cafe

!python --version
Python 3.11.11

Funciones

El beneficio de las funciones es que nos permiten reutilizar el código y evitar repetirnos.

Las funciones se definen con la palabra clave def y tienen la sintaxis

def nombre_funcion(parametros):
    pasos de la funcion

    #si no se pone return, la función devuelve None
    return algo

Para devolver un valor utilizamos la palabra clave return.

def hola_funcion():  # `:` es obligatorio
    print("Hola ciencia de datos en producción")
hola_funcion()
Hola ciencia de datos en producción

si no se pone return, la función devuelve None

salida = hola_funcion()
print(salida)
Hola ciencia de datos en producción
None
def cubo(x):  # `:` es obligatorio
    # el cuerpo de la función esta definido
    # por la indentación (espacios en blanco)

    # para devolver valores se usa `return`
    return x**3
out = cubo(4)
out
64

Ejemplo de una función mas compleja

  • ¿Que hace esta función?
  • ¿Que tipo de datos recibe?
  • ¿Que tipo de datos devuelve?
def algo(a):
    # recordar la indentación en Python
    s = 1
    for e in a:
        s = s * e
    return s
# sera que funciona?
mi_lista = ["a", "b", "c"]
algo(mi_lista)
---------------------------------------------------------------------------

TypeError                                 Traceback (most recent call last)

Cell In[8], line 3
      1 # sera que funciona?
      2 mi_lista = ["a", "b", "c"]
----> 3 algo(mi_lista)


Cell In[7], line 5, in algo(a)
      3 s = 1
      4 for e in a:
----> 5     s = s * e
      6 return s


TypeError: can't multiply sequence by non-int of type 'str'
# y ahora?
mi_lista = [5, 2, 3, 4]
algo(mi_lista)

Buenas practicas básicas al definir Funciones

Ejemplo de la misma función pero con algunas buenas practicas de software:

  • usar nombres descriptivos para las funciones
  • usar nombres descriptivos para los argumentos
  • docstrings (documentación)
  • static typing

No es obligatorio para que funcione, pero es muy recomendable para entender que es lo que hace la función y tipos de datos se deben ingresar y que tipo de datos devuelve la función.

Esta información ayuda a otros programadores a entender el código y a nosotros mismos en el futuro.

Ademas de que ayuda a los IDEs y Herramientas de AI en el trabajo en la auto completar código, detección de errores y crear pruebas unitarias.

Leer la siguiente función y responder las preguntas anteriores

  • ¿Que hace esta función?
  • ¿Que tipo de datos recibe?
  • ¿Que tipo de datos devuelve?
def multiplicar_elementos_lista(lista_numeros: list[int | float]) -> int | float:
    """multiplicar todos los elementos de una lista de números.

    Args:
      lista_numeros (list[int | float]): Una lista de valores numéricos.

    Returns:
      int | float: La suma de todos los elementos.

    Examples:
        >>> multiplicar_elementos_lista([1, 2, 3])
        6
        >>> multiplicar_elementos_lista([1.5, 2.5, 3.5])
        13.125
    """
    resultado = 1
    for elemento in lista_numeros:
        resultado = resultado * elemento
    return resultado
mi_lista = [5, 2, 3, 4]
resultado_funcion = multiplicar_elementos_lista(mi_lista)
print(f"Los elementos de la lista multiplicados  = {resultado_funcion}")

Static Typing

Python es un lenguaje de programación dinámico, lo que significa que no es necesario especificar el tipo de datos de una variable cuando se declara. Python infiere el tipo de datos de la variable en tiempo de ejecución. Pero a partir de Python 3.5, se introdujo la anotación de tipo de datos, que es una forma de declarar el tipo de datos de una variable.

EL static typing es una forma de declarar el tipo de datos de una variable, esto no afecta el funcionamiento del código, pero ayuda a los programadores a entender el código en la revision de los pull request, re usar código y ayuda a los IDEs a detectar errores y a completar el código.

Se puede ver un ejemplo de static typing en la siguiente función, donde se especifica el tipo de datos que recibe y el tipo de datos que devuelve la función.

def suma(a: int, b: int) -> int:
    return a + b

type hints cheat sheet

Docstrings

Las docstrings son cadenas de texto que se encuentran en la primera línea de una función, clase, método o módulo. Se utilizan para documentar el código y explicar lo que hace una función o método. Las docstrings se pueden acceder utilizando el atributo __doc__ de la función o método

Los docstrings sirven para documentar el código y explicar lo que hace una función o método.

print(multiplicar_elementos_lista.__doc__)
# se puede ver los tipos de los argumentos y el tipo de retorno
multiplicar_elementos_lista.__annotations__

help()

Nos entrega la ayuda de una función, clase, etc

help(len)
# y la primera función que creamos?

help(algo)

Ayuda de la función creada con typing y docstrings



```python
help(multiplicar_elementos_lista)

Validación de argumentos

# Que ocurre con el siguiente código?
mi_lista = ["a", "b", "c"]
resultado_funcion = multiplicar_elementos_lista(mi_lista)

Que podemos hacer para evitar que se utilice la función con argumentos incorrectos?

R/ No se puede evitar, pero la estrategias son como se vio anteriormente:

Beartype

Tiene un decorador simple que se puede usar para validar los argumentos de una función si esta tiene bien definidos los tipos de datos.

# importar el decorador @beartype
from beartype import beartype
@beartype
def multiplicar_elementos_lista(lista_numeros: list[int | float]) -> int | float:
    """multiplicar todos los elementos de una lista de números.

    Args:
      lista_numeros (list[int | float]): Una lista de valores numéricos.

    Returns:
      int | float: La suma de todos los elementos.

    Examples:
        >>> multiplicar_elementos_lista([1, 2, 3])
        6
        >>> multiplicar_elementos_lista([1.5, 2.5, 3.5])
        13.125
    """
    resultado = 1
    for elemento in lista_numeros:
        resultado = resultado * elemento
    return resultado

Ahora al llamar la función con argumentos incorrectos, nos arrojara un error.

por que los argumentos no cumplen con el tipo de datos especificado en la función y ya sabemos directamente que debemos corregir los datos de entrada.

en el caso de no tener la validación de los datos de entrada el error se presentara por que falla la función y deberíamos revisar el código para encontrar el error.

mi_lista = ["a", "b", "c"]
resultado_funcion = multiplicar_elementos_lista(mi_lista)
multiplicar_elementos_lista([1.5, 2.5, 3.5])

Importar funciones de archivos externos

Crear un script de funciones y importarlas en otro archivo es algo básico para poder reutilizar el código.

Esto nos permite tener un código mas limpio, organizado y fácil de mantener.

por ejemplo creo un archivo en la misma carpeta del notebook llamado calculos.py con la siguiente función:

@beartype
def sumar_elementos_lista(lista_numeros: list[int | float]) -> int | float:
    """sumar todos los elementos de una lista de números.

    Args:
      lista_numeros (list[int | float]): Una lista de valores numéricos.

    Returns:
      int | float: La suma de todos los elementos.

    Examples:
        >>> sumar_elementos_lista([1, 2, 3])
        6
        >>> sumar_elementos_lista([1.5, 2.5, 3.5])
        7.5
    """
    resultado = 0.0
    for elemento in lista_numeros:
        resultado = resultado + elemento
    return resultado

se puede ahora llamar la función de dos maneras

import calculos

calculos.sumar_elementos_lista([1.5, 2.5, 3.5])

La forma anterior importa todas las funciones del archivo calculos.py pero no es recomendable ya que si el archivo tiene muchas funciones, se importaran todas y no sabremos cuales funciones estamos utilizando.

lo recomendable es importar solo la función que necesitamos

from calculos import sumar_elementos_lista

sumar_elementos_lista([1.5, 2.5, 3.5])

Para importar funciones, clases o métodos de scripts externos que estén en otras carpetas una opcion es agregar la ruta de la carpeta al sys.path para que python pueda encontrar el archivo.

Para mas información de como importar funciones de scripts que estan en otras carpetas revisar la siguiente documentación https://diveintopython.org/learn/classes/import#importing-classes-from-a-parent-directory-with-code-sys-path-code

Referencias

Phd. Jose R. Zapata