2017-06-30 3 views
-1

Warum gibt es None aus?Generatorfunktionen in Python verstehen

def hello(): 
    print("hello") 

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

for x in gen(): 
    print(x) 

Ergebnis ist:

hello 
None 
hello 
None 
hello 
None 

warum keine gedruckt wird ?? nicht hallo * 3?

+10

'hallo()' gibt nicht zurück => gibt implizit 'None' zurück. 'Hallo() ist keine' – falsetru

+2

Vielleicht meintest du das:' def hallo(): zurück "hallo" '? – falsetru

+3

Ich empfehle, Funktionen zuerst zu lesen. –

Antwort

3

Warum druckt es keine:

hier, wenn Sie print() aber return etwas tun, Python ein return automatisch am Ende hinzufügen.

Nehmen wir ein Beispiel siehe unter Verwendung dis

import dis 

def hello(): 
    print('hello') 

dis.dis(hello) 

Ausgang:

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

ist jetzt Lassen Sie sehen, wenn Sie eine explizite Werte zurückgeben:

import dis 

def hello(): 
    return 'hello' 

dis.dis(hello) 

Ausgabe:

0 LOAD_CONST    1 ('hello') 
    3 RETURN_VALUE 

Siehe, die LOAD_CONST 0 (None) wurde nicht das zweite Mal aufgerufen. Daher war der erste Wert, der geladen wurde, zurück.

Was Sie tun sollten Ihren Code zu verbessern:

Tun Sie dies, wenn Sie nur „Hallo“ in der hello Funktion müssen drucken.

ODER, Rückgabewert verwenden, in diesem Fall müssen Sie zurückgeben, anstatt zu drucken.

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) 

Aber es ist seltsam mehr yield zu nennen, besser eine Schleife macht ein StopIteration

beispiel

def hello(): 
    return "hello" 

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

x = gen() 

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

von Standard Funktionen None Typen zurückgeben zu vermeiden.

def hello(): 
    pass 

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

for x in gen(): 
    print(x) 

Ausgang:

None 
None 
None 

Was Generatoren sind?

Der Hauptunterschied zwischen Generatoren und Funktionen besteht darin, dass Sie Werte während des Betriebs erhalten können. Und nach einem Wert ist yield 'durch den Generator. und der nächste Wert wird zurückgegeben, der alte ist nicht im Speicher gespeichert.

Iterieren über einen Generator

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


for i in hello(): 
    print(i) 

Ausgang:

0 
1 
4 

Jetzt next()

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

gen = hello() 

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

Ausgang mit:

0 
1 
4 

So weit so gut. Recht? gen = hello() Hier gen wird ein Generatorobjekt.

Iterieren über eine Liste

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

Ausgang:

0 
1 
4 

gleiche Leistung? Ja gleicher Ausgang. Aber nur hier Unterschied ist, dass ich die my_list iterable beliebig oft verwenden kann, was ich will,

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) 

Ausgang:

0 
1 
4 

0 
1 
4 

Allerdings, wenn ich versuche, den Generator zu verwenden, wenn sie erschöpft ist.

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

gen = hello() 

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

Ausgabe

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

Wie dies zu überwinden? Erstellen Sie ein neues Generatorobjekt erneut und verwenden Sie.

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)) 

Ausgang:

0 
1 
4 
0 
1 
4 

Sie sehen den Unterschied? Hoffe ich war klar.