Página inmutable History Adjuntos

Cursos/Principiantes/Parte2

Nombre de la página: Cursos / Principiantes / Parte2



Funciones

Hasta el momento hemos visto ejemplos donde todo es secuencial y al mismo nivel:

Repasemos con:

Como en muchos otros lenguajes, en Python existe el concepto de función, el cual, en principio es el mismo que el de las matemáticas, o al menos eso intenta.

La razón principal del por que se deben de usar funciones, es por que aportan organización al proyecto y, permite afrontar problemas complicados en pequeñas partes.

Una función, abstrae un conjunto de definiciones imperativas sobre como se comportara el programa al momento de llamarla, como interfaz, se tienen los argumentos que se le envían y la función por su parte, puede regresar un valor sin importar el tipo de objeto que este sea.

   1 def <NOMBRE>(<ARGUMENTOS>):
   2    <DOCSTRING>
   3    <DECLARACIONES...
   4    return <VALOR_DE_RETORNO> >

Los argumentos de una función pueden ser de alguna de las siguientes formas:

1.-(a, b, c)
Cantidad, posición y nombre definido.
2.-(a=2, b=2)
Cantidad, posición, nombre y argumento predefinido.
3.-(*args)


args es una lista con todos los argumentos que se envíen a la función.

Donde solo se puede reconocer el orden, no el nombre al que refiere.
4.-(**kwargs)


kwargs es un diccionario con todos los argumentos que se envíen a la función.

Donde se puede conocer el nombre y el valor de cualquier argumento
5.- (a, b, *, c)


c es un argumento de tipo "keyword only", es decir, es necesario llamar a la función

especificando el nombre del argumento directamente en la llamada de la funcion.

Los cinco tipos de forma de definición de argumentos se pueden combinar de las siguiente manera: (a, b, c, d=1, e=2, *args, f, g=None, **kwargs)

(<1>, <2>, <3>, <5>, <4>), siguiendo ese orden.

Los siguientes son formas validas de parametrizar una función:

  • (nombre, edad)

  • (nombre, edad, apellido=None)

  • (nombre, edad, apellido=None, *hermanos) 

  • (nombre, edad, apellido=None, *hermanos, **experiencia)

  • (nombre, edad, apellido=None, *hermanos, ciudad,  **experiencia)

Ejemplos:

   1 def guardar_contacto_1(nombre, edad):
   2     """Guarda el contacto en forma más básica.
   3     """
   4     print("El contacto %s con edad %s ha sido guardado." % (nombre, edad))
   5 
   6 def guardar_contacto_2(nombre, edad, apellido=None):
   7     """Guarda el contacto con la posibilidad de agregar apellido.
   8     """
   9     if apellido is None:
  10         return guardar_contacto_1(nombre, edad)
  11     else:
  12         print("El contacto %s con edad %s "
  13               "y apellido %s ha sido guardado." % (nombre, edad, apellido))
  14 
  15 def guardar_contacto_3(nombre, edad, apellido=None, *hermanos):
  16     """Guarda el contacto en forma mas detallada con hermanos.
  17     """
  18     if apellido is None:
  19         guardar_contacto_1(nombre, edad)
  20     else:
  21         guardar_contacto_2(nombre, edad, apellido)
  22     print("Guardando hermanos de contacto")
  23     print(hermanos)
  24 
  25 def guardar_contacto_4(nombre, edad, apellido=None, *hermanos, **experiencia):
  26     """Guarda el contacto con el máximo contenido de detalles
  27     incluyendo el opcional apellido, hermanos y todo el conjunto
  28     de experiencias que este haya llegado a tener.
  29     """
  30     guardar_contacto_3(nombre, edad, apellido, *hermanos)
  31     print("Guardando experiencias: %s" % experiencia)
  32 
  33 def suma(a, b):
  34     return a + b
  35 
  36 def resta(a, b):
  37     return a - b
  38 
  39 # suma_n(1, 2, 3, 4, 5)
  40 def suma_n(*numeros):
  41     """Suma todos los argumentos que se le envie.
  42     """
  43     suma_total = 0
  44     for numero in numeros:
  45         suma_total =  suma(suma_total, numero)
  46     return suma_total
  47 
  48 def resta_n(*numeros):
  49     """Resta todos los argumentos que se le envie.
  50     """
  51     resta_total = 0
  52     for numero in numeros:
  53         resta_total = resta(resta_total, numero)
  54     return resta_total
  55 
  56 def func_para_op(op):
  57     """Determina la función adecuada para la operación
  58     deseada.
  59     """
  60     if op == '+':
  61         return suma
  62     elif op == '-':
  63         return resta
  64     elif op == '+n':
  65         return suma_n
  66     elif op == '-n':
  67         return resta_n
  68     else:
  69         raise Exception('Operación desconocida %s' % op)
  70 
  71 def max_args(op):
  72     """Determina la cantidad máxima de argumentos que soporta
  73     la operación que se recibe.
  74     Regresa un entero que indica el limite y
  75     None en caso de no tener limite.
  76     """
  77     if 'n' in op:
  78         return None
  79     else:
  80         return 2
  81 
  82 def operacion(op, *args):
  83     """Ejecuta la operación `op` con argumentos `args`.
  84     """
  85     func_op = func_para_op(op)
  86     mxargs = max_args(op)
  87     if mxargs is None or mxargs == len(args):
  88         return func_op(*args)
  89     else:
  90         raise Exception('Argumentos erroneos para la operacion '
  91                         '%s args[%s]' % (op, args))
  92 
  93 print(operacion('+', 1, 2))
  94 op = operacion
  95 print(op('+n',
  96          op('+', 1, 2),
  97          op('-', 1, 2),
  98          op('-n',
  99             op('+', 20,
 100                op('-', 30, 30)))))

Video de la charla