2008-11-23 25 views

Odpowiedz

2

spojrzeć na rachunku yield dokonania generatory.

Nie znam żadnego rubin, ale wydaje się, że szukasz to:

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


for i in loop(): 
    print "pass" 

Edycja: Zdaję sobie sprawę, jest to w zasadzie specjalizacji realnych kontynuacje, ale powinno być wystarczające dla większości cele. Użyj opcji yield, aby zwrócić kontynuację, a wiadomość .next() na generatorze (zwrócona po prostu wywołując loop()), aby ponownie wprowadzić.

+0

To nie jest takie proste, zobacz 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

Korzystanie generator_tools (do zainstalowania: '$ 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()) 

wyjściowa:

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

generator_tools jest dość ograniczony na to, co można skopiować, zobacz jego dokumentację. Nie nominowałbym narzędzi generatora jako zastępczego zamiennika dla callcc. – pts

2

Istnieje wiele słabych obejścia pracujące w szczególnych przypadkach (zobacz inne odpowiedzi na to pytanie), ale nie ma konstruktu języka Python, który jest równoważny z callcc lub który może być użyty do zbudowania czegoś równoważnego z callcc.

Możesz spróbować Stackless Python lub greenlet Pythona rozszerzenie, które zapewniają zarówno współprogram, na podstawie których można zbudować jeden-shot continutations, ale to jeszcze słabszy niż Ruby callcc (co zapewnia pełne kontynuacje).