Python équivalent des continuations avec Ruby
-
10-07-2019 - |
Question
Quel est l'équivalent Python du code suivant en 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
Référence: Les secrets du succès du développement léger, partie 9: les suites frameworks à base de personnel
La solution
L'article que vous avez cité contient un lien vers Des continuations simplifiées et illustrées dans la section Ressources, qui traite des continuations en langage Python.
Autres conseils
consultez le rendement déclaration pour faire des générateurs.
Je ne parle pas de rubis, mais on dirait 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 me rends bien compte qu’il s’agit essentiellement d’une spécialisation de suites réelles, mais que cela devrait suffire dans la plupart des cas. Utilisez yield
pour renvoyer la suite et le message .next ()
sur le générateur (renvoyé simplement en appelant loop ()
) pour être ressaisi.
Utilisation de generator_tools
(pour installer: ' $ easy_install générateur_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)
Il existe de nombreuses solutions de contournement qui fonctionnent dans des cas particuliers (voir d'autres réponses à cette question), mais il n'y a pas de construction en langage Python équivalente à callcc
ou pouvant être utilisée pour construire quelque chose d'équivalent. vers callcc
.
Vous voudrez peut-être essayer Stackless Python ou le greenlet L'extension Python, qui fournissent toutes les deux une liste de tâches, sur la base desquelles il est possible de créer des continutations uniques, mais qui sont encore plus faibles que le callcc de Ruby
(qui fournit des suites complètes).
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()