Funciones

Las funciones son la forma más simple de organizar el código de una aplicación y su nombre hace referencia a las funciones matemáticas. Es decir, una función debería realizar una tarea muy concreta y bien definida y probablemente devolver un resultado. En las secciones anteriores ya se han utilizado funciones, como abs():


In [3]:
a = abs(-3.4)
a


Out[3]:
3.4

Veremos ahora como escribir nuestras propias funciones. La función tiene un formato muy simple:

  • La palabra reservada def
  • El nombre de la función (que debería ser lo más descriptivo y concreto posible).
  • Una lista de parámetros entre paréntesis
  • Un bloque de código

Veamos un ejemplo:


In [1]:
def factorial(n):
    if n == 0:
        return 1
    
    return n * factorial(n - 1)

factorial(100)


Out[1]:
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000L

Se trata de una función recursiva (que realiza su trabajo llamándose a sí misma). Lo más destacable es el hecho de que los parámetros tambpoco tienen un tipo explícito. Eso implica que nada impide que se pueda llamar con un valor no numérico, pero obviamente fallará.


In [10]:
factorial("text")


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-5268b995b58a> in <module>()
----> 1 factorial("text")

<ipython-input-7-c7997581257e> in factorial(n)
      3         return 1
      4 
----> 5     return n * factorial(n -1)
      6 
      7 factorial(100)

TypeError: unsupported operand type(s) for -: 'str' and 'int'

Paso de parámetros

Las funciones Python pueden aceptar parámetros opciones (simpre que sean los últimos). Para ello debe definirse un valor por defecto:


In [17]:
def f(a, b, c=7, d=14):
    print("a={}, b={}, c={}, d={}".format(a, b, c, d))
    
f(1, 2)


a=1, b=2, c=7, d=14

In [18]:
f(1, 2, 3)


a=1, b=2, c=3, d=14

Es posible pasar parámetros en la llamada indicado su nombre. Se les llama parámetros nombrados (keyword arguments).


In [21]:
f(1, d=20, b=100)


a=1, b=100, c=7, d=20

Notar que no es posible utilizar parámetros posicionales (sin nombre) después de parámetros nombrados.


In [22]:
f(a=10, 20)


  File "<ipython-input-22-8b2658cb3547>", line 1
    f(a=10, 20)
SyntaxError: non-keyword arg after keyword arg

Empaquetado de argumentos (o listas de argumentos variables)

Es posible escribir funciones con una cantidad arbitraría de argumentos. Si se utiliza "*args", la función recibe una tupla que incluye todos los parámetros capturados:


In [1]:
def variable_args_func(*args):
    print(args)
    
variable_args_func(1, 'a', 3.0)


(1, 'a', 3.0)

Aunque es posible definir algunos argumentos conocidos:


In [6]:
def func_with_name_and_other(name, *args):
    print("name: '{}', other: {}".format(name, args))
    
func_with_name_and_other("foo")
func_with_name_and_other("bar", 4, 200, "bye")


name: 'foo', other: ()
name: 'bar', other: (4, 200, 'bye')

También es posible capturar los parámetros con el parámetro especial "**kargs":


In [7]:
def func_with_args_and_kargs(*args, **kargs):
    print("args: '{}', kargs: '{}'".format(args, kargs))
    
func_with_args_and_kargs(1, 2, title="great", finish=True)


args: '(1, 2)', kargs: '{'finish': True, 'title': 'great'}'