2017-06-30 144 views
-1

爲什麼它輸出None瞭解Python中的生成器函數

def hello(): 
    print("hello") 

def gen(): 
    yield hello(); 
    yield hello(); 
    yield hello(); 

for x in gen(): 
    print(x) 

結果是:

hello 
None 
hello 
None 
hello 
None 

爲何沒有被印刷?? 不是你好* 3?

+10

'hello()'不返回=>隱式返回'None'。 'hello()is None' – falsetru

+2

也許你的意思是:'def hello():return「hello」'? – falsetru

+3

我建議先閱讀函數。 –

回答

3

爲什麼它打印無

在這裏,當你print()但犯規return什麼,Python會自動在末尾添加一個return

讓我們看到使用的例子dis

import dis 

def hello(): 
    print('hello') 

dis.dis(hello) 

輸出:

 0 LOAD_CONST    1 ('hello') 
     3 PRINT_ITEM   
     4 PRINT_NEWLINE  
     5 LOAD_CONST    0 (None) 
     8 RETURN_VALUE  

現在讓我們來看看,當你返回一個明確的值:

import dis 

def hello(): 
    return 'hello' 

dis.dis(hello) 

輸出:

0 LOAD_CONST    1 ('hello') 
    3 RETURN_VALUE 

看,LOAD_CONST 0 (None)不是第二次。因此,加載的第一個值是返回。

你應該做些什麼來改善你的代碼

做到這一點,如果你只需要打印「你好」的hello函數內。

def hello(): 
    print("hello") 

def gen(): 
    yield hello() 
    yield hello() 
    yield hello() 

for x in gen(): 
    x 

或者,使用返回值,在這種情況下,您需要返回而不是打印。

def hello(): 
    return "hello" 
    ^Here I return rather than print hello 

def gen(): 
    yield hello() 
    yield hello() 
    yield hello() 

for x in gen(): 
    print(x) 

但它是怪異調用幾個yield,更好地做一個循環,以避免StopIteration

e.g

def hello(): 
    return "hello" 

def gen(): 
    while True: 
     yield hello() 

x = gen() 

for i in range(3): 
    print(x.next()) 
0

通過默認函數返回None類型。

def hello(): 
    pass 

def gen(): 
    yield hello(); 
    yield hello(); 
    yield hello(); 

for x in gen(): 
    print(x) 

輸出:

None 
None 
None 

什麼是發電機?

生成器和函數的主要區別在於您可以即時獲取值。並且發電機發出一個值爲yield後。並返回下一個值,舊的不是存儲在內存

迭代一個發電機

def hello(): 
    for x in range(3): 
     yield x*x 


for i in hello(): 
    print(i) 

輸出:

0 
1 
4 

現在使用next()

def hello(): 
    for x in range(3): 
     yield x*x 

gen = hello() 

for i in range(3): 
    print(next(gen)) 

輸出:

0 
1 
4 

到目前爲止好。對? gen = hello()這裏gen成爲一個發電機對象。

遍歷列表

my_list = [x*x for x in range(3)] 
for i in my_list: 
    print(i) 

輸出:

0 
1 
4 

相同的輸出?是相同的輸出。但這裏唯一的區別是,我可以使用my_list迭代任意數量的時候,我想,

my_list = [x*x for x in range(3)] 
for i in my_list: 
    print(i) 
print("\n") 
for i in my_list: 
    print(i) 

輸出:

0 
1 
4 

0 
1 
4 

但是,如果我嘗試使用發電機當它耗盡。

def hello(): 
    for x in range(3): 
     yield x*x 

gen = hello() 

for i in range(3): 
    print(next(gen)) 
next(gen) 

輸出

0 
1 
4 
Traceback (most recent call last): 
    File "/home/mr/sadas.py", line 12, in <module> 
    print(next(gen)) 
StopIteration 

如何克服呢?再次創建一個新的生成器對象並使用。

def hello(): 
    for x in range(3): 
     yield x*x 

gen = hello() 

for i in range(3): 
    print(next(gen)) 

gen = hello() 

for i in range(3): 
    print(next(gen)) 

輸出:

0 
1 
4 
0 
1 
4 

你看有什麼區別?希望我清楚。