Las funciones son uno de los elementos más importantes de la
programación en Python. Su objetivo es guardar en un bloque todas las acciones necesarias para ejecutar una determinada acción sobre los datos del código. Este bloque, será llamado todas las veces necesarias, sin tener que ser reescrito.
Para definir una función usamos la palabra clave “def”, seguido del nombre
de la función y los paréntesis. No debemos olvidar finalizar con los dos puntos y sangrar el código que contenga la función.
Otra cosa importante a tener en cuenta es que la función debe de ser
definida siempre antes de ser llamada. Lo mejor es definir las funciones en los
primeros pasos del código.
En el siguiente caso la función toma como nombre “saludo”.
def saludo():
print("Hola. Bienvenido al grupo.")
invitados=["Pedro", "Juan","Javier"]
for invitado in invitados:
print(f"Saludamos a {invitado}.")
saludo()Resultado:
Saludamos a Pedro.
Hola. Bienvenido al grupo.
Saludamos a Juan.
Hola. Bienvenido al grupo.
Saludamos a Javier.
Hola. Bienvenido al grupo.Funciones y Parámetros
El uso de las funciones se vuelve más interesante cuando les pasamos argumentos para que puedan trabajar con ellos. Para que esto pueda ser posible, al definir la función debemos añadir uno o más parámetros entre paréntesis. La función tomará los argumentos recibidos y los convertirá en parámetros para ser usados dentro de la función. Los argumentos pueden ser cualquier tipo de dato,
pero deben de coincidir con los parámetros que espera recibir la función.
def saludo(nombre):
print(f"Saludamos a {nombre}.")
print(f"Hola {nombre}. Bienvenido al grupo.")
invitados=["Pedro", "Juan","Javier"]
for invitado in invitados:
saludo(invitado)Resultado:
Saludamos a Pedro.
Hola Pedro. Bienvenido al grupo.
Saludamos a Juan.
Hola Juan. Bienvenido al grupo.
Saludamos a Javier.
Hola Javier. Bienvenido al grupo.En la definición de la función podemos añadir tantos parámetros como creamos necesarios. Como regla general, al invocar a la función deberemos de añadir tantos argumentos como parámetros estén incluidos en su definición, y además deben de estar informados en el mismo orden y contener el mismo tipo de
datos.
def producto(nombre,cantidad,precio_unidad,iva):
total_sin_iva=cantidad*precio_unidad
resultado=round(total_sin_iva*(1+(iva/100)),2)
print(f"Producto: {nombre}. Total producto: {resultado}.")
return (resultado)
compra_1=producto("leche",10,1.28,4)
compra_2=producto("pan",20,0.65,4)
compra_3=producto("aceite",2,8.20,12)
total_compra=round((compra_1+compra_2+compra_3),2)
print(f"\nEl importe de su compra es: {total_compra}")Resultado:
Producto: leche. Total producto: 13.31.
Producto: pan. Total producto: 13.52.
Producto: aceite. Total producto: 18.37.
El importe de su compra es: 45.2La instrucció return
En el ejemplo anterior, hemos visto que se ha añadido una instrucción
“return” en la definición de la función. Esta instrucción no es obligada, pero nos ayuda a devolver al flujo principal del programa un dato que luego puede seguir utilizándose.
Si la función va a devolver un dato (con “return”), es posible llamarla como
valor de una variable que pasará a tomar ese dato como valor. También podemos aplicar el valor de la función directamente al código (como cualquier otro valor).
def factorial(entero):
calculo=1
while entero>1:
calculo=entero*calculo
entero=entero-1
return (calculo)
print(factorial(6))Resultado:
720Si no existe valor de retorno, la función se llamará simplemente
nombrándola, como hemos visto con la función “saludo”, sin ser necesaria ninguna variable que almacene el resultado.
Si no existe return, la función se ejecuta hasta que llega al final de su código. En ese momento se produce el retorno al flujo principal.
También puede devolverse el control a otra función, ya que una función puede ser llamada desde otra función.
def saludo(nombre):
print(f"Saludamos a {nombre}")
def nuevo_alumno(alumno):
print(f"El alumno {alumno} es nuevo en la clase.")
saludo(alumno)
listado=["Juan","Pedro","Luis"]
for nuevo in listado:
nuevo_alumno(nuevo) Resultado:
El alumno Juan es nuevo en la clase.
Saludamos a Juan
El alumno Pedro es nuevo en la clase.
Saludamos a Pedro
El alumno Luis es nuevo en la clase.
Saludamos a LuisTambién debemos de tener en cuenta que si una función llama a otra, esta otra debe de estar definida en el código antes que la que llama.
La instrucción return (si existe), no debe de estar siempre al final del código de la función. Puede estar incluida en cualquier otro lugar de su código. En el momento en que aparezca un “return” (puede haber varios incluidos dentro de la misma función), se devuelve automáticamente el control a la parte del programa que llama a la función.
Veamos un ejemplo con una función que recibe como
argumento una lista.
def mi_funcion(listado):
for numero in listado:
if numero % 7 == 0:
mensaje=f"El número {numero} es divisible entre 7."
return (mensaje)
mensaje="No hemos encontrado en la lista ningún número divisible entre 7."
return(mensaje)
listado=[5,76,14,28,100]
print(mi_funcion(listado))Resultado:
El número 14 es divisible entre 7.La instrucción “return” puede estar incluida en una función tanto con un valor de retorno, como con un valor vacío (si no queremos devolver nada).
def mi_funcion(listado):
for numero in listado:
if numero% 7 ==0:
print(f"El número {numero} es divisible entre 7.")
return
print("No hemos encontrado en la lista ningún número divisible entre 7.")
return
listado=[5,76,14,22,100]
mi_funcion(listado)Resultado:
El número 14 es divisible entre 7.Parámetros por defecto.
Al definir la función, podemos especificar valores por defecto para sus parámetros. Esto implica, que si al llamar a las funciones omitimos los correspondientes argumentos, la función tomará como parámetros estos valores.
Cuando usamos estos parámetros por defecto, debemos incluirlos al
final de la definición (primero deben ir los parámetros que deben de ser pasados en todo caso).
def area(altura, base=10):
mi_area=base*altura
return(mi_area)
medida_1=14
medida_2=18
print(f"El área es {area(medida_1,medida_2)}.")
print(f"Ahora el área es {area(medida_1)}.")Resultado:
El área es 252.
Ahora el área es 140.En la primera llamada a la función área, se han tomados como parámetros los dos argumentos pasados. En la segunda llamada, como solo se ha pasado un argumento, la función toma como segundo parámetro el que tiene por defecto.
Funciones y variables. Variables locales y global variable
Un detalle muy importante a tener en cuenta es el valor que pueden tomar las variables dentro de una función. Una variable declarada dentro de una función, solo será reconocida dentro de dicha función, (dar valor a una variable dentro de la función, equivale a definirla).
def ahorro_banco(ahorro_anterior,intereses_banco):
ahorro=(ahorro_anterior)+intereses_banco*(1-irpf)
print("Según la función, el ahorro sumados intereses del banco es:",ahorro)
salario=2000
irpf=0.15
gastos=1500
ahorro=salario*(1-irpf)-gastos
print("El ahorro antes de intereses banco es:",ahorro)
ahorro_banco(ahorro,500)
print("El ahorro sumados ahorro banco es:",ahorro)Resultado:
El ahorro antes de intereses banco es: 200.0
Según la función, el ahorro sumados intereses del banco es: 625.0
El ahorro sumados ahorro banco es: 200.0Vemos que la variable ahorro definida dentro de la función, queda definida y restringida a la propia función. Cuando el control vuelve al programa principal, la variable ahorro retoma el valor que tenía antes.
Para que una variable tome un valor dentro de una función, y este valor sea respetado fuera de dicha función, tenemos que declarar la variable tanto dentro como fuera de la función como global.
def ahorro_banco(ahorro_anterior,intereses_banco):
global ahorro
ahorro=(ahorro_anterior)+intereses_banco*(1-irpf)
print("Según la función, el ahorro sumados intereses del banco es:",ahorro)
global ahorro
salario=2000
irpf=0.15
gastos=1500
ahorro=salario*(1-irpf)-gastos
print("El ahorro antes de intereses banco es:",ahorro)
ahorro_banco(ahorro,500)
print("El ahorro sumados ahorro banco es:",ahorro)Resultado:
El ahorro antes de intereses banco es: 200.0
Según la función, el ahorro sumados intereses del banco es: 625.0
El ahorro sumados ahorro banco es: 625.0Los parámetros serán variables locales dentro de la función
Cuando una función recibe un parámetro (y aunque ese parámetro tenga el mismo nombre que otra variable definida fuera de la función), el parámetro pasará a ser una variable local para la función. Si se modifica dentro de la función, no quedará modificada también fuera.
def division(dividendo,divisor):
dividendo=dividendo+1
division=dividendo/divisor
return division
dividendo=9
divisor=2
resultado=division(dividendo,divisor)
print(resultado)
print(dividendo)Resultado:
5.0
9Hemos modificado dentro de la función el parámetro dividendo, sin embargo la variable dividendo ha quedado sin tocar fuera de la función.
Funciones y Listas.
Una excepción a lo indicado en el punto anterior, son las listas. Podemos modificar una lista definida en el flujo principal, desde dentro de una función. Ni siquiera es necesario pasarla como parámetro de la función.
def mi_funcion():
lista.append(5)
for k in range (0,len(lista)):
lista[k]=lista[k]**3
lista=[1,2,3,4]
mi_funcion()
print(lista)Resultado:
[1, 8, 27, 64, 125]Sin embargo debemos de saber que si creamos una lista dentro de una función, con el mismo nombre que tiene otra lista definida dentro del flujo principal, entonces sí que se crea una nueva lista dentro de la función que será diferente a la lista del flujo principal. Esto puede ocasionar muchos errores. Por lo tanto no es
nada recomendable que una lista del flujo principal y una lista definida dentro de una función, tengan ambas el mismo nombre.
def mi_funcion():
lista=[100,200,300]
print("La lista de la funcion es:",lista)
lista=[1,2,3,4]
mi_funcion()
print("La lista del flujo principal es:",lista)Resultado:
La lista de la funcion es: [100, 200, 300]
La lista del flujo principal es: [1, 2, 3, 4]def mi_funcion():
lista.append(5)
for k in range (0,len(lista)):
lista[k]=lista[k]**3
print("La lista es:",lista)
lista=[100,200,300]
print("Ahora la lista es:",lista)
lista=[1,2,3,4]
mi_funcion()
print("La lista del flujo principal es:",lista)Resultado:
File "/home/keduardo/Documentos/Python/prueba.py", line 2, in mi_funcion
lista.append(5)
^^^^^
UnboundLocalError: cannot access local variable 'lista' where it is not associated with a valueEste código dará error. La función entiende que la lista se crea en la
penúltima línea de su código. Sin embargo se está haciendo mención a “su” lista en las líneas anteriores a la definición de dicha lista.
Si deseamos volver a definir una lista en una función que ya está definida en el flujo principal, y queremos que ambas listas sigan siendo la misma, debemos de utilizar la opción “global”.
El siguiendo código no dará error y es totalmente fiable, ya que en todo momento estamos haciendo referencia a la misma lista, gracias al uso de “global”.
def mi_funcion():
global lista
lista.append(5)
for k in range (0,len(lista)):
lista[k]=lista[k]**3
print("La lista es:",lista)
lista=[100,200,300]
print("Ahora la lista es:",lista)
global lista
lista=[1,2,3,4]
mi_funcion()
print("La lista del flujo principal es:",lista)Resultado:
La lista es: [1, 8, 27, 64, 125]
Ahora la lista es: [100, 200, 300]
La lista del flujo principal es: [100, 200, 300]Archivo de Funciones
Una de las principales ventajas de las funciones, es la de separar el código
que corresponde a una determinada tarea dentro del programa, del resto del
código. Esta ventaja se ve ampliada cuando este código separado, podemos
guardarlo en un archivo independiente, que puede contener múltiples funciones relacionadas. Este archivo (y las funciones que contenga), puede ser reutilizado después en otros programas.
def intereses(cantidad,tipo,meses):
interes=cantidad+(cantidad*tipo/100*meses)
return(interes)
def descuentos(cantidad,descuento):
midescuento=cantidad-(cantidad*descuento/100)
return(midescuento)
def nominas(sueldo,primas,irpf):
bruto=sueldo+primas
neto=bruto-(bruto*irpf/100)
return(neto)Este código anterior relacionado con las finanzas, puede ser guardado en un archivo llamado misfinancieras.py
Es muy recomendable que el archivo que contiene las funciones, y el archivo que contiene el programa principal se encuentren en la misma carpeta del ordenador.
Las funciones que contiene este archivo pueden ser utilizadas en nuestro programa utilizando el comando import.
Para hacer uso de las funciones que contiene el archivo, debemos de nombrarlas utilizando como prefijo el nombre de dicho archivo, seguido de punto y el nombre de la función.
import misfinancieras
misueldo=misfinancieras.nominas(1200,500,12)
print(misueldo)Resultado:
1496.0from archivo import funcion
Puede ocurrir que el archivo que queremos importar contenga un número indeterminado de funciones. Para evitar que se nos cargue en memoria demasiado código, con el peligro añadido de que una de las funciones pueda contener variables o funciones que ya tengamos definida en nuestro código principal, podemos hacer uso de una importación selectiva:
from misfinancieras import nominas,intereses
misueldo=nominas(1200,500,12)
print(misueldo)
misintereses=intereses(1500,1,6)
print(misintereses)Resultado:
1496.0
1590.0Ahora solo hemos importado algunas funciones. Vemos el formato que debe de tener la importación, primero nombramos el archivo importado (precedido de “from”) y después las funciones que nos interesan (precedidas de “import” y separadas por comas).
Otra ventaja más al hacerlo de esta manera es que para hacer uso de las funciones solo las nombramos a ellas, sin necesidad de nombrar el archivo de procedencia.
Es bastante probable que al escribir el código, nuestro entorno de
programación (por ejemplo Visual Studio Code), nos identifique el nombre de archivo como un posible error. Esto no nos debe de preocupar. Se debe a que en el momento de escribir el código, el asistente de escritura de programación no conoce la palabra asociada al nombre del archivo.
Es frecuente utilizar la instrucción import, para utilizar en nuestros
programas módulos que ya vienen con python por defecto. Por ejemplo, para utilizar datos tipo fecha, deberemos importar el módulo datetime.
Es importante a la hora de guardar un archivo Python, no utilizar nunca como nombre de archivo una palabra reservada para Python (el nombre de una instrucción, un comando, un módulo python…), si lo hacemos podemos caer en errores difíciles de detectar.
from archivo import función as alias
Si el nombre de la función que necesitamos importar puede dar problemas
con los nombres que ya tenemos en nuestro código, podemos usar un alias para la nueva función importada:
from misfinancieras import nominas as salario, intereses as renta
misueldo=salario(1200,500,12)
print(misueldo)
misintereses=renta(1500,1,6)
print(misintereses)Resultado:
1496.0
1590.0Recursividad de las funciones
Una de las características de las funciones es la recursividad. Gracias a ella, una función puede llamarse a sí misma. Por ejemplo, podemos hallar el factorial de un número con una función recursiva:
def mifactorial(n):
global numero
if n>2:
print(f"{numero}*{n-1}={numero*(n-1)}")
numero=numero*(n-1)
return (mifactorial(n-1))
global numero
numero=8
inicio=numero
print(numero)
if numero>2:
mifactorial(numero)
print(f"Factorial de {inicio} es {numero}.")
else:
print("El factorial de 2 es 2.")Resultado:
8
8*7=56
56*6=336
336*5=1680
1680*4=6720
6720*3=20160
20160*2=40320
Factorial de 8 es 40320.Esta función se va llamando a sí misma hasta que n vale 3. En ese momento se multiplica el acumulado por (n-1) que es 2 y se vuelve a llamar con el valor de 2. Pero en la nueva llamada ya no se ejecuta el condicional y se sale devolviendo el control al flujo principal.
Otro ejemplo de recursividad. En este caso la función se va llamando a sí
misma hasta que la cadena queda vacía, momento en el cual se sale de la función.
def alfabeto(cadena):
if len(cadena)==0:
return
else:
print(cadena)
cadena=cadena[:-1]
alfabeto(cadena)
cadena="abcdefghijklmnopqrstuvwxyz"
alfabeto(cadena)Resultado:
abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxy
abcdefghijklmnopqrstuvwx
abcdefghijklmnopqrstuvw
abcdefghijklmnopqrstuv
abcdefghijklmnopqrstu
abcdefghijklmnopqrst
abcdefghijklmnopqrs
abcdefghijklmnopqr
abcdefghijklmnopq
abcdefghijklmnop
abcdefghijklmno
abcdefghijklmn
abcdefghijklm
abcdefghijkl
abcdefghijk
abcdefghij
abcdefghi
abcdefgh
abcdefg
abcdef
abcde
abcd
abc
ab
a
