2008-11-23 13 views

Respuesta

2

echar un vistazo a la declaración yield para hacer generadores.

yo no hablaba nada de rubí, pero parece que usted está buscando para ello:

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


for i in loop(): 
    print "pass" 

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

+0

No es tan fácil, consulte http://stackoverflow.com/questions/312794/#313073 – jfs

0
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() 
2

Usando 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) 
+0

generator_tools es bastante limitado en lo que puede copiar, consulte su documentación. No recomendaría que generator_tools sea un reemplazo directo para callcc. – pts

2

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

es posible que desee probar Stackless Python o la extensión de Python greenlet, los cuales proveen corrutinas, en base a las cuales es posible construir continutations de un solo disparo, pero eso es aún más débil que Ruby callcc (que proporciona continuaciones completos).