example - python import reduce from functools
Generadores de Ruby vs generadores de Python (3)
El uso de Ruby''s Enumerator en la clase StopIteration internamente, consulte ¿Cómo funcionan los enumeradores en Ruby 1.9.1?
(Sólo está envuelto si lo usas en cada llamada). Así que diría que están bastante cerca. Dicho esto, no estoy seguro de qué debería hacer un método de cierre en un enumerador, exactamente ... ¿limpieza, quizás? (Los generadores de Python probablemente se beneficiarían con un rebobinado; tenga en cuenta que en Ruby, algunos enumeradores no responden al rebobinado, por lo que generan una excepción cuando llaman a ese método).
He estado investigando las similitudes / diferencias entre los generadores de Ruby y Python (conocidos como Enumerators
en Ruby), y hasta ahora puedo decir que son bastante equivalentes.
Sin embargo, una diferencia que he notado es que los generadores de Python admiten un método close()
mientras que los generadores de Ruby no lo hacen. De los documentos de Python se dice que el método close()
hace lo siguiente:
Genera una salida de generador en el punto donde se pausó la función del generador. Si la función del generador genera un StopIteration (al salir normalmente, o debido a que ya está cerrado) o GeneratorExit (al no detectar la excepción), el cierre vuelve a su llamador ".
¿Hay alguna buena razón por la que Ruby Enumerators
no admita el método close()
? ¿O es una omisión accidental?
También descubrí que Ruby Enumerators
compatible con el método rewind()
pero los generadores de Python no ... ¿existe alguna razón para esto?
Gracias
Esta documentación para el método de rebobinado es un poco escasa en los detalles. Pero para "volver a empezar", el generador tendría que hacer una de dos cosas:
- recuerde su salida completa, repita esa salida una vez rebobinada, luego reanude lo que estaba haciendo antes
- reinicie su estado interno de manera que se repita la misma salida sin otros efectos secundarios no deseados
El segundo de estos no siempre es posible; por ejemplo, si el generador emite buffers de bytes de la red, la salida no es completamente una función del estado interno. Pero cualquier generador que use la primera técnica necesariamente debe construir un búfer cada vez más grande en la memoria a medida que se usa. Tales generadores ofrecen poco beneficio de rendimiento sobre las listas.
Por lo tanto, llego a la conclusión de que el método de rewind
Ruby debe ser opcional y no siempre es compatible con una clase de enumerador concreto. Entonces, si los diseñadores de Python valoran el principio de sustitución de Liskov , eso los llevaría a no requerir un método de este tipo en todos los generadores.
Los generadores se basan en la pila, los enumeradores de Ruby a menudo son especializados (a nivel de intérprete) y no se basan en la pila.