Domanda

Qual è l'equivalente di Python del seguente codice in 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

Riferimento: Segreti del successo dello sviluppo leggero, Parte 9: Continuazioni framework basati su

È stato utile?

Soluzione

L'articolo che hai citato contiene un link a Continuazioni rese semplici e illustrate nella sezione Risorse, che parla di continuazioni nel linguaggio Python.

Altri suggerimenti

dai un'occhiata alla yield dichiarazione per creare generatori.

Non parlo nessun rubino, ma sembra che tu stia cercando questo:

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


for i in loop():
    print "pass"

Modifica: mi rendo conto che questa è fondamentalmente una specializzazione di continuazioni reali, ma dovrebbe essere sufficiente per la maggior parte degli scopi. Usa yield per restituire la continuazione e il messaggio .next () sul generatore (restituito semplicemente chiamando loop () ) per rientrare.

Utilizzo di generator_tools (per installare: ' $ 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())

Output:

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

Esistono molte soluzioni alternative deboli che funzionano in casi speciali (vedi altre risposte a questa domanda), ma non esiste un costrutto in linguaggio Python equivalente a callcc o che può essere usato per costruire qualcosa di equivalente su callcc .

Potresti provare Stackless Python o greenlet estensione Python, entrambi i quali forniscono coroutine, in base alla quale è possibile costruire continutazioni one-shot, ma è ancora più debole di callcc di Ruby (che fornisce continuazioni complete).

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()
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top