iterators, generators, decorators y yield

En python, el protocolo de iterator es un objeto que implementa dos metodos:
  • __iter__() - este retorna el objeto de iterador
  • next()  - que retorna el siguiente elemento dentro de una secuencia
Los iteradores tienen las siguientes ventajas:
  • Podemos crear un codigo mas limpio
  • Nos ayuda a ahorrarnos recursos de memoria
  • podemos trabajar con secuencias infinitas
Cuando hablamos que nos ayuda a ahorrarnos recursos de memoria quiere decir que no es necesario cargar todo el set de datos en memoria. Aqui podemos ver algunos ejemplos de la clase iter() dentro de una cadena.
cadena = "Enciclopedia"
for i in cadena:
   print i,

print i
it = iter(cadena)
print it.next()
print it.next()
print list(it)

Como ves aqui pusimos dos ejemplos, la forma clasica de establecer un bucle, y la forma en la cual iter() va llevando a cabo la secuencia.

Generators

Los generators son rutinas especiales que pueden ser utilizados pueden ser usados para controlar el comportamieindo de un bucle. Un generaton funciona de una manera similar a una funcion retornando un arreglo. Un generator tiene parametros, estos pueden ser invocados y genera una secuencia de numeros. La diferencia con funciones, estas pueden regresar un array completo, un generador usa yields (rendimiento) de cada valor.

Caractaresticas de generators:

  • Son definidos con def
  • Emplea el uso de yield
  • Puede usar multiples keywords yield
  • Retorna un iterator
Ejemplo:
def gen():
   x, y = 1, 2
   yield x, y
   x += 1
   yield x, y

it = gen()
print it.next()
print it.next()
try:
   print it.next()
except StopIteration:
   print "Fin de la iteracion"

Yield

Es importante ver como funciona yield en este caso. Para empezar yield significa rendimiento, y lo que hace en este generador (definido como gen) es que nos retorna un valor durante el ciclo y hace que el iterador continue a partir del resultado de yield. Enteniendolo yield afecta el flujo del generador y el iterator nos regresa en el caso de nuestro ejemplo nos da: (1,2) y (2,2) que son los resultados de nuestro primer y segundo yield.

Para entender mejor yields, nos dice la documentacion que yield es una expresion que unicamente puede usarse dentro de una funcion generator y unicamente puede ser usada en el cuerpo de la funcion definida. Tambien que esta es usada junto con los generadores para controlar el flujo del procedimiento ya que al invocarse una funcion de tipo genenerator esta procede hasta el primer yield y pausa el proceso. Sin embargo, todas las variables, subrutinas, y valores son retenidos hasta que se itera al siguiente yield.

Esto hace que tanto los generators como los yields funcionen como subrutinas con la excepcion que el generador no tiene control de lo que sigue despues del ultimo yield, y que esto debe pasare al quien llamo al generador.

Decorators


Comments