2016-10-15 15 views
6

Tôi nghĩ rằng tôi có thể làm cho mã python (2.7.10) của tôi đơn giản hơn bằng cách truy cập trực tiếp vào chỉ mục của một giá trị được truyền tới một máy phát qua send, và đã làm cho mã này ngạc nhiên. sau đó tôi phát hiện ra một chỉ số áp dụng cho yield không thực sự làm bất cứ điều gì, cũng không ném một ngoại lệ:Tại sao sản lượng có thể được lập chỉ mục?

def gen1(): 
    t = yield[0] 
    assert t 
    yield False 

g = gen1() 
next(g) 
g.send('char_str') 

Tuy nhiên, nếu tôi cố gắng index yield ba lần hoặc nhiều hơn, tôi nhận được một ngoại lệ:

def gen1(): 
    t = yield[0][0][0] 
    assert t 
    yield False 

g = gen1() 
next(g) 
g.send('char_str') 

mà ném

TypeError: 'int' object has no attribute '__getitem__' 

Đây là hành vi không phù hợp bất thường, và tôi đã tự hỏi nếu có một lời giải thích trực quan cho những gì indexing năng suất i thực sự đang làm gì?

Trả lời

13

Bạn không lập chỉ mục. Bạn đang có một danh sách; biểu thức yield[0] là thực sự chỉ giống như sau (nhưng không có một biến):

lst = [0] 
yield lst 

Nếu bạn nhìn vào những gì next() trả về có bạn muốn đã nhận được danh sách đó:

>>> def gen1(): 
... t = yield[0] 
... assert t 
... yield False 
... 
>>> g = gen1() 
>>> next(g) 
[0] 

Bạn don' t để có khoảng cách giữa yield[0], đó là tất cả.

Trường hợp ngoại lệ là do bạn cố gắng áp dụng các đăng ký vào chứa 0 số nguyên:

>>> [0]  # list with one element, the int value 0 
[0] 
>>> [0][0]  # indexing the first element, so 0 
0 
>>> [0][0][0] # trying to index the 0 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'int' object is not subscriptable 

Nếu bạn muốn đánh chỉ mục một giá trị gửi đến các máy phát điện, đặt dấu ngoặc xung quanh khái niệm yield:

t = (yield)[0] 

Demo:

>>> def gen1(): 
...  t = (yield)[0] 
...  print 'Received: {!r}'.format(t) 
...  yield False 
... 
>>> g = gen1() 
>>> next(g) 
>>> g.send('foo') 
Received: 'f' 
False 
Các vấn đề liên quan