Pregunta

¿Cuál es el equivalente en Python del siguiente código en Ruby?

def loop
  cont=nil
  for i in 1..4
    puts i
    callcc {|continuation| cont=continuation} if i==2
  end
  return cont
end

> c=loop
1
2
3
4
> c.call
3
4

Referencia: Secretos del éxito de desarrollo ligero, Parte 9: Continuaciones basados ??en marcos

¿Fue útil?

Solución

El artículo que citó contiene un enlace a Continuaciones simplificadas e ilustradas en la sección Recursos, que habla sobre las continuaciones en el lenguaje Python.

Otros consejos

eche un vistazo al rendimiento declaración para hacer generadores.

No hablo rubí, pero parece que estás buscando esto:

def loop():
    for i in xrange(1,5):
        print i
        if i == 2:
            yield


for i in loop():
    print "pass"

Editar: Me doy cuenta de que esto es básicamente una especialización de continuaciones reales, pero debería ser suficiente para la mayoría de los propósitos. Use yield para devolver la continuación y el mensaje .next () en el generador (devuelto simplemente llamando a loop () ) para volver a ingresar.

Uso de generator_tools (para instalar: ' $ easy_install generator_tools '):

from generator_tools import copy_generator

def _callg(generator, generator_copy=None):
    for _ in generator: # run to the end
        pass
    if generator_copy is not None:
        return lambda: _callg(copy_generator(generator_copy))

def loop(c):
    c.next() # advance to yield's expression
    return _callg(c, copy_generator(c))

if __name__ == '__main__':
    def loop_gen():
        i = 1
        while i <= 4:
            print i
            if i == 2:
                yield
            i += 1

    c = loop(loop_gen())
    print("c:", c)
    for _ in range(2):
        print("c():", c())

Salida:

1
2
3
4
('c:', <function <lambda> at 0x00A9AC70>)
3
4
('c():', None)
3
4
('c():', None)

Hay muchas soluciones débiles que funcionan en casos especiales (ver otras respuestas a esta pregunta), pero no hay una construcción de lenguaje Python que sea equivalente a callcc o que pueda usarse para construir algo equivalente a callcc .

Es posible que desee probar Stackless Python o el greenlet Extensión de Python, las cuales proporcionan corutinas, en base a las cuales es posible construir continuas de una sola vez, pero eso es aún más débil que el callcc de Ruby (que proporciona continuaciones completas).

def loop():    
    def f(i, cont=[None]):        
        for i in range(i, 5):
            print i
            if i == 2:
                cont[0] = lambda i=i+1: f(i)
        return cont[0]
    return f(1)

if __name__ == '__main__':
    c = loop()
    c()
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top