Python equivalente di continuazioni con Ruby
-
10-07-2019 - |
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
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()