2017-08-22 1 views
0

Hier ist ein Endlos-Looper, dem Zeilennummern hinzugefügt wurden, um die Verfolgung der Programmausführung zu erleichtern.Python: Verstehen der Ertragszuweisung im Generator

def infinite_looper(objects): 
    count = 0 
    print("row 35") 
    while True: 
     print("row 37") 
     if count >= len(objects): 
      count = 0 
     print("Row 40") 
     message = yield objects[count] 
     print("row 42") 
     print("The message is "+str(message)) 
     print("row 44") 
     if message != None: 
      count = 0 if message < 0 else message 
      print("row 47, count = "+str(count)) 
     else: 
      count += 1 
      print("row 50") 
     print("Row 51") 

x = infinite_looper("abcdefghijkl") 

print("executing next 1st time") 
print(next(x)) 

print("executing next 2nd time") 
print(next(x)) 

print("executing send 1st time") 
print(x.send(10)) 

Die Ausgabe lautet:

executing next 1st time 
row 35 
row 37 
Row 40 
a 
executing next 2nd time 
row 42 
The message is None 
row 44 
row 50 
Row 51 
row 37 
Row 40 
b 
executing send 1st time 
row 42 
The message is 10 
row 44 
row 47, count = 10 
Row 51 
row 37 
Row 40 
k 

Was ich nicht verstehe ist, was passiert, bevor "executing send 1st time" gedruckt wird. b wurde gerade vom Programm ausgegeben, vermutlich über die Zeile message = yield objects[count] in infinite_looper. Aber dann wird der Wert der Nachricht von None auf 10 geändert, obwohl message = yield objects[count] bereits ausgeführt wurde! Meine einzige Theorie ist, dass das Yield-Schlüsselwort so funktioniert, dass die Ausführung in seiner Zeile "bleibt", nachdem es ausgeführt wurde, und eine send-Anweisung an den Looper die gleiche Zeile (in diesem Fall message = yield objects[count]) erneut ausführen lässt. Sonst hätten wir:

executing send 1st time 
row 42 
The message is **None** 

Ist das eine korrekte Theorie? Mehr Details wie das funktioniert?

Antwort

2

Aber dann wird der Wert der Nachricht an 10 von None auch geändert, obwohl message = yield objects[count] bereits ausgeführt wurde!

Nr ergab einen Wert hat, aber bis zum send Anruf, der Wert des Ausdrucks yield objects[count] wurde message nicht bestimmt oder zugewiesen. Die Ausführung des Generators wird während der Ausführung der Linie unterbrochen. (Beachten Sie, dass der Wert eines yield Ausdruck ist nicht der gleiche wie der Wert, den es liefert.)

Der x.send(10) Aufruf bewirkt, dass der yield Ausdruckswert nehmen 10, und dieser Wert ist, was zu message zugeordnet ist.

+0

Brilliant, das ist das Stück, das ich vermisste. – Sahand