selon la réponse à cette question , la rupture de rendement en C # équivaut à retourner en python. dans le cas normal, 'return' arrête en effet un générateur. Mais si votre fonction ne fait rien d'autre que retourner, vous obtiendrez un Aucun, pas un itérateur vide, qui est retourné par yield break en C #
def generate_nothing():
return
for i in generate_nothing():
print i
vous obtiendrez une TypeError: l'objet 'NoneType' n'est pas itérable. mais si j'ajoute un rendement jamais exécuté avant le retour, cette fonction retourne ce que j'attends.
def generate_nothing():
if False: yield None
return
si fonctionne mais semble câblé. Qui a une meilleure idée?
merci,
def generate_nothing():
return
yield
Une bonne façon de gérer cela consiste à augmenter StopIteration qui est généré lorsque votre itérateur n'a plus rien à céder et que next()
est appelée. Cela sortira également gracieusement d'une boucle for sans rien à l'intérieur de la boucle exécutée.
Par exemple, étant donné un Tuple (0, 1, 2, 3)
Je veux obtenir des paires qui se chevauchent ((0, 1), (1, 2), (2, 3))
. Je pourrais le faire comme ça:
def pairs(numbers):
if len(numbers) < 2:
raise StopIteration
for i, number in enumerate(numbers[1:]):
yield numbers[i], number
Maintenant, pairs
gère en toute sécurité les listes avec 1 nombre ou moins.
def generate_nothing():
return iter([])
La partie amusante est que les deux fonctions ont le même bytecode. Il y a probablement un indicateur qui prend la valeur generator
lorsque le compilateur de bytecode trouve le mot clé yield
.
>>> def f():
... return
>>> def g():
... if False: yield
#in Python2 you can use 0 instead of False to achieve the same result
>>> from dis import dis
>>> dis(f)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE
>>> dis(g)
2 0 LOAD_CONST 0 (None)
3 RETURN_VALUE