Funciones de Python


Una función es un bloque de código con un nombre asociado, que recibe cero o más argumentos como entrada, sigue una secuencia de sentencias, la cuales ejecuta una operación deseada y devuelve un valor y/o realiza una tarea, este bloque puede ser llamados cuando se necesite.


El uso de funciones es un componente muy importante del paradigma de la programación llamada estructurada, y tiene varias ventajas:
  • modularización: permite segmentar un programa complejo en una serie de partes o módulos más simples, facilitando así la programación y el depurado.
  • reutilización: permite reutilizar una misma función en distintos programas.
Python dispone de una serie de funciones integradas al lenguaje, y también permite crear funciones definidas por el usuario para ser usadas en su propios programas.

Definición de una función.

De forma general, las funciones en Python se definen de la siguiente manera:
def <nombre>(<parámetros>):
    <código>
Las funciones se invocan de la siguiente manera:
<nombre>(<argumentos>)
Durante el transcurso del curso se han invocado múltiples funciones.

Definición de una función mínima.

>>>> def funcion():
...      pass
La declaración pass.
La declaración pass no realiza ninguna acción, pero evita que se genere un error de indentación al crear una función vacía.
Cuando la función que se acaba de definir se invoca, no ocurre nada.
Ejemplo:
In [2]:
def funcion():
    pass
In [3]:
funcion()
In [4]:
type(funcion)
Out[4]:
function
 

Una función con código.

Ejemplo: La siguiente función desplegará un mensaje al ser invocada.
In [5]:
def saludo():
    print('Hola')
In [6]:
saludo()
 
Hola
 

Las funciones son objetos.

En Python, las funciones son objetos.
Ejemplo:
In [7]:
def saludo():
    print( 'Hola')
In [8]:
dir(saludo)
Out[8]:
['__annotations__',
 '__call__',
 '__class__',
 '__closure__',
 '__code__',
 '__defaults__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__format__',
 '__ge__',
 '__get__',
 '__getattribute__',
 '__globals__',
 '__gt__',
 '__hash__',
 '__init__',
 '__kwdefaults__',
 '__le__',
 '__lt__',
 '__module__',
 '__name__',
 '__ne__',
 '__new__',
 '__qualname__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__str__',
 '__subclasshook__']
 

Introspección.

Python puede generar documentación a partir del código y los elementos de un objeto y particularmente de los comentarios de estilo docstring. El primer comentario usando docstring justo debajo de def se utiliza como parte de la documentación de la función.
Ejemplo:
In [9]:
def saludo():
    '''Imprime un mensaje de texto.'''
    print( 'Hola')
In [10]:
help(saludo)
 
Help on function saludo in module __main__:

saludo()
    Imprime un mensaje de texto.

 


 

Parámetros y argumentos.

Es posible ingresar datos al ser invocadas a estos datos se les denomina argumentos y son ligados a nombres, los cuales se conocen como parámetros. El número de argumentos ingresados debe corresponder al número de parámetros que se definen. En caso de que no se ingresen los argumentos necesarios, se generará un error de tipo TypeError.
Ejemplo:
In [27]:
def suma(primero, segundo):
    '''Despliega la suma de dos objetos'''
    print(primero + segundo)
In [28]:
suma(12, 5)
 
17
In [29]:
suma('Hola, ', 'Mundo.')
 
Hola, Mundo.
In [30]:
suma('Hola')
 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-30-9824c60d998d> in <module>()
----> 1 suma('Hola')

TypeError: suma() missing 1 required positional argument: 'segundo'
In [31]:
suma('Hola, ', 'Ḿundo', '.')
 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-31-a8e7b848ade8> in <module>()
----> 1 suma('Hola, ', 'Ḿundo', '.')

TypeError: suma() takes 2 positional arguments but 3 were given
 

Parámetros con argumentos por defecto.

Es posible asignar valores por defecto a cada parámetro definido en una función mediante el operado de asignación ( = ).
Si a todos los parámetros se les asigna un valor, entonces no es necesario ingresar argumentos al invocar la función, ya que dichos valores serán utilizados. Los argumentos que se ingresen se irán sustituyendo de izquierda a derecha.
Ejemplo:
In [32]:
def suma(primero=1, segundo=3):
    '''Despliega la suma de dos objetos'''
    print(primero + segundo)
In [33]:
suma()
 
4
In [34]:
suma(2)
 
5
In [35]:
suma(2, 5)
 
7
 
Si sólo se asignarán valores por defecto a algún parámetro, dichos valores se deben dejar al final de la lista de parámetros. De no ser así, se generará un error de tipo SyntaxError.
Ejemplo:
In [36]:
def suma(primero, segundo=3):
    '''Despliega la suma de dos objetos'''
    print(primero + segundo)
In [37]:
suma(2)
 
5
In [38]:
suma("2", "43")
 
243
 
Ejemplo:
In [39]:
def suma(primero=1, segundo):
    '''Despliega la suma de dos objetos'''
    print(primero + segundo)
 
  File "<ipython-input-39-57fd5f85113f>", line 1
    def suma(primero=1, segundo):
            ^
SyntaxError: non-default argument follows default argument
 

Captura de varios argumentos en un parámetro de tipo tuple (args).

Es posible definir un parámetro que acepte un número indeterminado de argumentos y que éstos queden guardados dentro de un objeto tipo tuple. Para esto, basta preceder al nombre del parámetro con un solo asterisco ( * ).
Ejemplo:
In [40]:
def promedio(*muestras):
    '''Calcula el promedio de la muestra correspondiente a todos los parámetros ingresados.'''
    promedio = sum(muestras)/len(muestras)
    print('El promedio de la muestra de %d elementos es %.3f.' %(len(muestras), promedio))
In [41]:
promedio(1, 3, 5, 8, 11, 24, 90, 29)
promedio(14, 38, 1)
 
El promedio de la muestra de 8 elementos es 21.375.
El promedio de la muestra de 3 elementos es 17.667.
 
El parámetro que recibe más de un argumento debe definirse al final de la lista de parámetros. Ejemplo:
In [42]:
def promedio(titulo, *muestras):
    '''Calcula el promedio de la muestra correspondiente a todos los parámetros ingresados con excepción
       del primero, el cual será utilizado como título.'''
    promedio = sum(muestras)/len(muestras)
    print(titulo)
    print('El promedio de la muestra de %d elementos es %.3f.' %(len(muestras), promedio))

promedio('Conteo de abejas en campo.', 34, 45, 61, 23, 47, 41, 52)
 
Conteo de abejas en campo.
El promedio de la muestra de 7 elementos es 43.286.
 

Captura de varios argumentos en un parámetro de tipo dict (kargs).

Es posible definir los parámetros y valores que se ingresan a una función mediante el uso de la sintaxis nombre = valor y que estos parámetros queden almacenados en un objeto tipo dict. Para esto, basta preceder al nombre del parámetro con doble asterisco ( ** ).
Ejemplo:
In [43]:
def superficie(**dato):
    '''Calcula la superficie de una figura geométrica si los parámetros  ingresados
       coinciden.'''
    if dato["tipo"] == "Rectángulo":
        superficie = float(dato["base"]) * float(dato["altura"])
    elif dato["tipo"] == "Triángulo":
        superficie = float(dato["base"]) * float(dato["altura"]) / 2
    elif dato["tipo"] == "Círculo":
        superficie = float(dato["radio"]) ** 2 * 3.14259265
    else:
        print("No puedo calcular la superficie.")
    print("La superficie del %s es de %.3f" % (dato["tipo"].lower(), superficie))
In [44]:
superficie(base=22, altura=30, tipo="Rectángulo")
 
La superficie del rectángulo es de 660.000
In [45]:
superficie(tipo="Círculo", radio = 35)
 
La superficie del círculo es de 3849.676
 

Funciones que regresan valores y cerraduras.

Todas las funciones regresan un valor al finalizar su ejecución al cual se le puede asignar un nombre si se desea conservarlo. Por defecto, el valor que regresan es None, el cual a diferencia de otros valores no es desplegado por el intérprete.
Ejemplo:
In [46]:
def funcion():
    pass
In [47]:
resultado = funcion()
print(resultado)
 
None
In [48]:
resultado
 

La expresión return.

La expresión return se utiliza para regresar un objeto específico a su ámbito superior y acto seguido dar por terminada la ejecución de la función de forma similar a break. Pueden incluirse varias expresiones return en una función, pero sólo se ejecutará la primera que se encuentre. La sintaxis es la siguiente:
return <objeto>
Ejemplo:
In [49]:
def promedio(*muestras):
    return (len(muestras), sum(muestras) / len(muestras))
In [50]:
media = promedio(1, 3, 5, 8, 11, 24, 90, 29)
In [51]:
print('El promedio de la muestra de %d elementos es %.3f.' %(media))
 
El promedio de la muestra de 8 elementos es 21.375.
 

Cerraduras.

El valor que regresa una función se conoce como "cerradura" o "closure" y tiene características muy particulares ya que se encuentra justo entre el ámbito local de una función y su ámbito superior.

Funciones anidadas.

Python permite definir funciones dentro de otras funciones.
Ejemplo:
In [52]:
def lista_primos(limite=100):
    '''Genera una lista de los números primos comprendidos entre el 2 y el valor de limite.'''
    #La lista inicia con el número 2
    lista = [2]
   
    def esprimo(numero):
        '''Valida si numero es divisible entre algún elemento de lista. De ocurrir, 
        regresa False. De lo contrario, regresa True.'''
        for primo in lista:
            if numero % primo == 0:
                return False
        return True
    #Se realizará una iteración de cada número entero desde 3 hasta el valor de limite.
    for numero in range(3, limite + 1):
        #Si esprimo(numero) regresa True, añade el valor de numero a lista
        if esprimo(numero):
            lista.append(numero)
    return lista
In [53]:
lista_primos(103)
Out[53]:
[2,
 3,
 5,
 7,
 11,
 13,
 17,
 19,
 23,
 29,
 31,
 37,
 41,
 43,
 47,
 53,
 59,
 61,
 67,
 71,
 73,
 79,
 83,
 89,
 97,
 101,
 103]
 
En el ejemplo anterior se definió a la función esprimo() dentro de la función listaprimos(). Como se puede observar, el nombre lista está en el espacio de nombres de listaprimos(), pero al estar en un entorno superior al ámbito de esprimo(), éste puede acceder a lista.
 

Recursividad.

Python permite hacer llamadas recursivas a una función. Es decir, que la función se invoque a si misma.
Cada vez que una función se invoca a si misma, Python crea un nuevo objeto de tipo function con las mismas características que la función original, pero con un ámbito totalmente nuevo y de nivel inferior a la función original.
Ejemplo:
In [54]:
def factorial(numero):
    if numero == 1:
        return 1
    else:
        fact = numero * factorial(numero - 1)
        return fact
In [55]:
factorial(5)
Out[55]:
120
 
En este caso, la función factorial() se invoca recursivamente, pero cada vez que lo hace, el valor del argumento decrece en 1 de forma sucesiva hasta que el parámetro numero alcanza el valor de 1 y regresa dicho valor. Es entonces que la cerradura de la función de nivel inferior se multiplica por el parámetro numero de la función superior hasta llegar a la función de más alto nivel.
Ahora se incluirán algunas modificaciones al ejemplo anterior para ilustrar el proceso.
In [56]:
def factorial(numero):
    print('En este ámbito, numero =', numero)
    if numero == 1:
        print('Llegó al final.\nRegresa 1!')
        return 1
    else:
        fact = numero * factorial(numero - 1)
        print('Regresa %d!' %numero)
        return fact
In [57]:
factorial(5)
 
En este ámbito, numero = 5
En este ámbito, numero = 4
En este ámbito, numero = 3
En este ámbito, numero = 2
En este ámbito, numero = 1
Llegó al final.
Regresa 1!
Regresa 2!
Regresa 3!
Regresa 4!
Regresa 5!
Out[57]:
120
 

Funciones de orden superior.

Las funciones de orden superior son funciones que aceptan funciones como argumentos y a su vez regresan funciones.
Ejemplo:
La función html() puede recibir una función y regresará una función que de por resultado el cuerpo básico de un documento en HTML5 que envuelva al resultado de la función usada como argumento. Por otro lado, la función parrafo() transforma un texto en un párrafo rodeado por las etiquetas HTML correspondientes.
In [58]:
def html(funcion):
    '''Añade las etiquetas básicas de un documento HTML5 al elemento 
       resultante del argumento funcion.'''
    etiquetas = "<html>\n  <head>\n    <title>Página</title>\n  </head>\n  <body>\n    {}\n  </body>\n</html>"
    def empaqueta(texto):
        '''Permite encerrar entre etiquetas de HTML5 al resultado de funcion(texto).'''
        return etiquetas.format(funcion(texto))
    return empaqueta
In [59]:
help(html)
 
Help on function html in module __main__:

html(funcion)
    Añade las etiquetas básicas de un documento HTML5 al elemento 
    resultante del argumento funcion.

In [60]:
def parrafo(texto):
    '''Encierra entre las etiquetas de párrafo al elemento texto.'''
    return '<p>' + str(texto) + '</p>'
In [61]:
print(parrafo('Hola, Mundo.'))
 
<p>Hola, Mundo.</p>
In [62]:
help(parrafo)
 
Help on function parrafo in module __main__:

parrafo(texto)
    Encierra entre las etiquetas de párrafo al elemento texto.

In [63]:
print(html(parrafo)('Hola, Mundo.'))
 
<html>
  <head>
    <title>Página</title>
  </head>
  <body>
    <p>Hola, Mundo.</p>
  </body>
</html>
In [64]:
help(html(parrafo))
 
Help on function empaqueta in module __main__:

empaqueta(texto)
    Permite encerrar entre etiquetas de HTML5 al resultado de funcion(texto).

 

Decoradores.

Los decoradores son un recurso de Python que permite aplicar una función de orden superior a otra función con la siguiente sintaxis.
@<nombre de función de orden superior>
def <nombre>(<argumentos>):
    ...
    ...
Ejemplo:
Se utilizará el decorador de la función html() aplicado a la función parrafo().
In [65]:
def html(funcion):
    '''Añade las etiquetas básicas de un documento HTML5 al elemento 
       resultante del argumento funcion.'''
    etiquetas = "<html>\n  <head>\n    <title>Página</title>\n  </head>\n  <body>\n    {}\n  </body>\n</html>"
    def empaqueta(texto):
        '''Permite encerrar entre etiquetas de HTML5 al resultado de funcion(texto).'''
        return etiquetas.format(funcion(texto))
    return empaqueta
In [66]:
@html
def parrafo(texto):
    '''Encierra entre las etiquetas de párrafo al elemento texto.'''
    return '<p>' + str(texto) + '</p>'
In [67]:
print(parrafo("Hola, Mundo."))
 
<html>
  <head>
    <title>Página</title>
  </head>
  <body>
    <p>Hola, Mundo.</p>
  </body>
</html>
In [68]:
help(parrafo)
 
Help on function empaqueta in module __main__:

empaqueta(texto)
    Permite encerrar entre etiquetas de HTML5 al resultado de funcion(texto).

 

Definición de funciones con la declaración lambda.

Python permite definir funciones en una sola línea mediante el uso del la expresión lambda con la siguiente sintaxis:
lambda <argumentos>: <código>
A este tipo de funciones se les conoce como funciones lambda o funciones anónimas debido a que no requieren de un nombre para ser definidas.
Para nombrar a estas funciones se utiliza el operador de asignación ( = ).
Ejemplo:
In [69]:
saluda = lambda texto='extraño', ancho=50: print('Hola, {}.'.format(texto).center(ancho))
In [70]:
type(saluda)
Out[70]:
function
In [71]:
saluda()
 
                  Hola, extraño.                  
In [72]:
saluda('Mundo', 20)
 
    Hola, Mundo.    
 

Funciones lambda con estructuras if... else.

Las funciones lambda permiten incluir condicionales dentro de su sintaxis de la siguiente forma:
lambda <argumentos>: <expresion_1> if <condición> else <expresión_2>
Ejemplo:
es_par es una función que valida si un número entero ingresado como parámetro es par.
In [73]:
es_par = lambda numero: True if numero % 2 == 0 else False
In [74]:
es_par(2)
Out[74]:
True
In [75]:
es_par(3)
Out[75]:
False
 
Ejemplo:
La función factorial calcula el factorial de un número mediante recursividad.
In [76]:
factorial = lambda numero: numero * factorial(numero - 1) if numero > 1 else 1
In [77]:
factorial(5)
Out[77]:
120

Comentarios

Entradas más populares de este blog