Einfache Antwort
Wenn die Funktion mindestens eine yield
Anweisung wird die Funktion automatisch zur Generatorfunktion. Wenn Sie eine Generatorfunktion aufrufen, führt Python den Code in der Generatorfunktion aus, bis yield
Anweisung auftreten. yield
Anweisung friert die Funktion mit all ihren internen Zuständen ein. Wenn Sie die Generatorfunktion erneut aufrufen, setzt Python die Ausführung des Codes in der Generatorfunktion ab der eingefrorenen Position fort, bis yield
Aussage immer wieder vorkommen. Die Generatorfunktion führt den Code aus, bis die Generatorfunktion abläuft, ohne yield
Erklärung.
Benchmark
Erstellen Sie eine Liste und geben Sie sie zurück:
def my_range(n):
my_list = []
i = 0
while i < n:
my_list.append(i)
i += 1
return my_list
@profile
def function():
my_sum = 0
my_values = my_range(1000000)
for my_value in my_values:
my_sum += my_value
function()
Ergebnisse mit:
Total time: 1.07901 s
Timer unit: 1e-06 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
9 @profile
10 def function():
11 1 1.1 1.1 0.0 my_sum = 0
12 1 494875.0 494875.0 45.9 my_values = my_range(1000000)
13 1000001 262842.1 0.3 24.4 for my_value in my_values:
14 1000000 321289.8 0.3 29.8 my_sum += my_value
Line # Mem usage Increment Occurences Line Contents
============================================================
9 40.168 MiB 40.168 MiB 1 @profile
10 def function():
11 40.168 MiB 0.000 MiB 1 my_sum = 0
12 78.914 MiB 38.746 MiB 1 my_values = my_range(1000000)
13 78.941 MiB 0.012 MiB 1000001 for my_value in my_values:
14 78.941 MiB 0.016 MiB 1000000 my_sum += my_value
Erzeugen Sie Werte im laufenden Betrieb:
def my_range(n):
i = 0
while i < n:
yield i
i += 1
@profile
def function():
my_sum = 0
for my_value in my_range(1000000):
my_sum += my_value
function()
Ergebnisse mit:
Total time: 1.24841 s
Timer unit: 1e-06 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
7 @profile
8 def function():
9 1 1.1 1.1 0.0 my_sum = 0
10
11 1000001 895617.3 0.9 71.7 for my_value in my_range(1000000):
12 1000000 352793.7 0.4 28.3 my_sum += my_value
Line # Mem usage Increment Occurences Line Contents
============================================================
7 40.168 MiB 40.168 MiB 1 @profile
8 def function():
9 40.168 MiB 0.000 MiB 1 my_sum = 0
10
11 40.203 MiB 0.016 MiB 1000001 for my_value in my_range(1000000):
12 40.203 MiB 0.020 MiB 1000000 my_sum += my_value
Zusammenfassung
Die Generatorfunktion benötigt etwas mehr Zeit für die Ausführung als eine Funktion, die eine Liste zurückgibt, aber sie verbraucht viel weniger Speicher.