Der Python-Generator ist nützlich, aber sobald Sie ihn in einer Schleife mit einer for-Anweisung verwenden, sieht er wie ein Carappo aus, wenn Sie versuchen, ihn in einer for-Anweisung erneut zu verwenden.
def i(n):
yield n + 1
yield n + 2
g = i(10)
print('first time:')
for n in g:
print(n)
print('second time:')
for n in g:
print(n)
Die Ausgabe ist
first time:
11
12
second time:
Es wird sein. In der zweiten for-Schleife werden keine Elemente iteriert.
In Situationen, in denen Sie möchten, dass "11" und "12" in der zweiten und den folgenden "for" -Schleifen zurückkehren, haben die folgenden Techniken funktioniert.
class ReiteratableWrapper(object):
def __init__(self, f):
self._f = f
def __iter__(self):
return self._f()
def i(n):
yield n + 1
yield n + 2
import functools
f = functools.partial(i, 10)
g2 = ReiteratableWrapper(f)
for n in g2:
print(n)
for n in g2:
print(n)
Die Klasse "ReiteratableWrapper" übernimmt eine Generatorfunktion. Da es aufgerufen wird, ohne intern ein Argument anzugeben, erstellen Sie, wenn Sie einen Generatoraufruf mit einem Argument durchführen möchten, eine Funktion ohne Argument, die das Argument mit der Funktion functools.partial
usw. wie im Beispiel bindet.
Ausdrücke, die im Kontext nach in der for-Anweisung ausgewertet werden, werden als "iter" -Methode bezeichnet. Daher erstellt eine Instanz von "Reiteratable Wrapper" jedes Mal automatisch einen neuen Generator.
Jedes Mal, wenn die Methode iter ausgewertet wird, wird die Generatorfunktion ausgewertet und ausgeführt. Wenn also beim Aufrufen der Generatorfunktion ein Nebeneffekt auftritt, z. B. eine Begrenzung der Häufigkeit, mit der die Generatorfunktion ausgeführt werden kann, kann sie nicht wiederholt verwendet werden. Ich denke da ist etwas.
Ich denke, die diesmal eingeführte Technik ist effektiv für Inhalte, die wiederholt werden können, z. B. das Lesen aus einer Datei, um Speicherplatz zu sparen, jedes Mal eine Abfrage an die Datenbank zu senden und in der angegebenen Reihenfolge zu iterieren.
Recommended Posts