2008-11-23 6 views

Répondre

2

un coup d'oeil à la déclaration yield pour faire des générateurs.

Je ne parle pas de rubis, mais il semble que vous cherchez ceci:

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


for i in loop(): 
    print "pass" 

Edit: Je sais que cela est essentiellement une spécialisation des continuations réels, mais il devrait être suffisant pour la plupart fins. Utilisez yield pour renvoyer la continuation et le message .next() sur le générateur (retourné en appelant simplement loop()) pour entrer de nouveau.

+0

Ce n'est pas si simple, voir 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

En utilisant generator_tools (à installer: '$ 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()) 

Sortie:

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

generator_tools est assez limité sur ce qu'il peut copier, voir sa documentation. Je ne nommerais pas generator_tools comme remplaçant de callcc. – pts

2

Il y a beaucoup de solutions de contournement faibles qui travaillent dans des cas particuliers (voir d'autres réponses à cette question), mais il n'y a pas de construction en langage Python qui soit équivalente à callcc ou qui peut être utilisée pour construire quelque chose d'équivalent à callcc.

Vous voudrez peut-être essayer Stackless Python ou greenlet extension Python, qui offrent tous deux coroutines, à partir desquels il est possible de construire continutations one-shot, mais qui est encore plus faible que Ruby callcc (qui fournit des continuations complets).