2017-07-19 41 views
5

Đọc về coroutines Python, tôi đi qua mã này:Tại sao máy phát Python/coroutine này mất một giá trị?

def countdown(n): 
    print("Start from {}".format(n)) 
    while n >= 0: 
     print("Yielding {}".format(n)) 
     newv = yield n 
     if newv is not None: 
      n = newv 
     else: 
      n -= 1 

c = countdown(5) 
for n in c: 
    print(n) 
    if n == 5: c.send(2) 

mà tò mò kết quả đầu ra:

Start from 5 
Yielding 5 
5 
Yielding 3 
Yielding 2 
2 
Yielding 1 
1 
Yielding 0 
0 

Đặc biệt, nó bỏ lỡ in 3. Tại sao?


Câu hỏi được tham chiếu không trả lời được câu hỏi này vì tôi không hỏi send là gì. Nó sẽ gửi các giá trị trở lại hàm. Những gì tôi hỏi là lý do tại sao, sau khi tôi phát hành send(3), sản lượng tiếp theo, sẽ mang lại 3, không gây ra vòng lặp for in 3.

+0

Đầu tiên, nó cũng bỏ lỡ 4. Thứ hai, bạn nghĩ 'c.send (3)' làm gì? – alfasin

+0

@alfasin Nó bỏ lỡ 4 vì 'c.send (3)'. Vấn đề là mã nên đặt 'n' thành 3, và sau đó trên vòng lặp tiếp theo, năng suất 3. Nhưng nó không được in. Tại sao? – Ritzymon

+0

nó trở nên rõ ràng hơn nếu bạn thêm một định dạng 'print ('newv: {}'. (Newv)' trong 'if newv không phải là None:' block –

Trả lời

4

Bạn chưa bao giờ kiểm tra giá trị trả lại của cuộc gọi c.send(3). Trong thực tế, có vẻ như phương pháp send tự nâng cao trình phát, vì vậy số điện thoại 3 bị thiếu của bạn là yield được thực hiện trong cuộc gọi c.send(3) đó.

def countdown(n): 
    while n >= 0: 
     newv = yield n 
     if newv is not None: 
      n = newv 
     else: 
      n -= 1 

c = countdown(5) 
print(next(c)) 
print(c.send(3)) 
print(next(c)) 

Kết quả sẽ là:

5 
3 
2 

Nó thực sự là documented:

generator.send (giá trị)

Sơ yếu lý lịch thực hiện và “gửi” một giá trị vào chức năng máy phát điện. Đối số giá trị trở thành kết quả của biểu thức lợi nhuận hiện tại. Phương thức send() trả về giá trị tiếp theo do máy phát điện tạo ra hoặc tăng StopIteration nếu máy phát thoát ra mà không có giá trị khác.

0

Bạn đang thất bại trong c.send(). Bạn đang so sánh khi n == 5, nhưng bạn không gửi 5 (trong chức năng của bạn là n-1), bạn đang gửi 3. Ví dụ, nó không in 4.

Hãy thử cùng một mã nhưng với c.send(5), nó sẽ in từ 5 đến 0.

c = countdown(5) 
for n in c: 
    print(n) 
    if n == 5: c.send(5) 
+0

Thực ra, nó không in từ 5 đến 0. Nó in ' 5', '3',' 2', '1',' 0', thiếu '4'. – Ritzymon

Các vấn đề liên quan