天天看點

yield 和 return

作用類似于return,隻不過yield傳回的是一個疊代器(generator),可以配合特殊的方法:next()、send()函數使用。

1.調用:含有yield特殊字的函數,被調用之後傳回的是一個疊代器

def foo():
    i = 1
    print("starting...")
    while True:
        yield i+1
        i+=1
        print(i)

g = foo()
print(g)

》》》
<generator object foo at 0x0000020430EEC8E0>
           

可以看到,不會執行foo函數的内容,g為一個generator。

2.next(g)    當調用next()函數時,會執行到yield。   nex(g)就是yield傳回的東西。

def foo():
    i = 1
    print("starting...")
    while True:
        yield i+1
        i+=1
        print(i)

g = foo()
print(g)
print(next(g))
print("*"*20)
print(next(g))

》》》
<generator object foo at 0x0000028838AFC8E0>
starting...
2
********************
2
3
           

        再執行next()函數時,會接着上一次next執行完yield的地方繼續向下執行

3.send()函數,指派。否則 yield是不會進行指派操作的。  同時send()方法包含了next()方法,執行send()會自動執行next()

def foo():
    i = 1
    print("starting...")
    while True:
        res = yield i+1
        i+=1
        print(i)
        print('res:',res)

g = foo()
print(g)
print(next(g))
print("*"*20)
print(next(g))

》》》
<generator object foo at 0x000001CB255BC8E0>
starting...
2
********************
2
res: None
3
           

      由上面可以看到,雖然有 res = yield i+1,這個貌似指派的操作,但是yield并不會有進行指派

def foo():
    i = 1
    print("starting...")
    while True:
        res = yield i+1
        i+=1
        print(i)
        print('res:',res)

g = foo()
print(g)
print(next(g))

print("*"*20)
print(g.send(7))

》》》
<generator object foo at 0x00000187FDD3C8E0>
starting...
2
********************
2
res: 7
3
           

     上段代碼可見,在第一次執行next()函數之後,疊代器會停留在yield處。

     在執行g.send(7)時,會接着在yield處繼續執行,進行指派。然後自動再執行next()函數,即運作到下一個yield結束。

4.yield 和 return 的差別

從上面可以看出,yield操作之後,後續是可以繼續有代碼的,下一次next()的時候,後續的代碼也是會被執行的。

而return不同,函數隻要執行了return,這個函數就結束了,return後面的任何代碼是不會被執行的。并且 return沒有标記的作用,不能配合send() 進行指派。