python中yield用法詳解


      今天看python學習視頻學到生成器這一塊時始終弄不懂yield的用法及其原理,在網上詳細查看yield的用法之后總結一下yield的使用方法。

      先看一個簡單的yield語句:

def fib(max):
    n, a, b = 0, 0, 1
    while n < max:
        yield b
        a, b = b, a + b
        n = n + 1

      這是有關斐波那契數列的一個函數,當時正是這個函數中的yield使我困惑導致整個函數不能理解。這個函數包含yield,實際上這已經是一個生成器(generator)了,這與普通的函數有很大的不同。

def h():
    print 'hello'
    yield 6
h()

      可以看到,調用h()之后,print 語句並沒有執行!這就是yield,那么,如何讓print 語句執行呢?這就是后面要討論的問題,通過后面的討論和學習,就會明白yield的工作原理了。

2. yield是一個表達式

      Python2.5以前,yield是一個語句,但現在2.5中,yield是一個表達式(Expression),比如:

      x = yield 6

表達式(yield 6)的返回值將賦值給x,所以,認為 x = 5 是錯誤的。那么如何獲取(yield 5)的返回值呢?需要用到后面要介紹的send(msg)方法。

3. 透過next()語句看原理

      現在,我們來揭曉yield的工作原理。我們知道,我們上面的h()被調用后並沒有執行,因為它有yield表達式,因此,我們通過next()語句讓它執行。next()語句將恢復Generator執行,並直到下一個yield表達式處。比如:

def h():
    print('hello')
    yield 6
    print('python!')
c = h()
c.__next__()       #這里是雙下划線

      c.next()調用后,h()開始執行,直到遇到yield 6,因此輸出結果:

      hello

當我們再次調用c.next()時,會繼續執行,直到找到下一個yield表達式。由於后面沒有yield了,因此會拋出異常:

hello
Traceback (most recent call last):
python!
  File "C:/Users/zxj/PycharmProjects/firstProject/day4/test.py", line 29, in <module>
    c.__next__()
StopIteration

4. send(msg) 與 next()

      了解了next()如何讓包含yield的函數執行后,我們再來看另外一個非常重要的函數send(msg)。其實next()和send()在一定意義上作用是相似的,區別是send()可以傳遞yield表達式的值進去,而next()不能傳遞特定的值,只能傳遞None進去。因此,我們可以看做

c.next() 和 c.send(None) 作用是一樣的。

來看這個例子: 

def h():
    print('hello'),
    x = yield 6
    print m
    y = yield 23
    print 'python'
c = h()
c.__next__()  #相當於c.send(None)
c.send('ok')  #(yield 6)表達式被賦予了'ok'

輸出的結果為:

hello

ok

      需要提醒的是,第一次調用時,請使用next()語句或是send(None),不能使用send發送一個非None的值,否則會出錯的,因為沒有yield語句來接收這個值。

5. send(msg) 與 next()的返回值

      send(msg) 和 next()是有返回值的,它們的返回值很特殊,返回的是下一個yield表達式的參數。比如yield 6,則返回 6 。到這里,是不是明白了一些什么東西?我們再延續上面的例子:

def h():
    print('hello')
    x = yield 6
    print(m)
    y = yield 23
    print (y)
c = h()
x = c.__next__()  #x 獲取了yield 6 的參數值 6
y = c.send('ok')  #y 獲取了yield 23 的參數值23
print(x,y)

      輸出結果:

hello
ok
6 23

      以上就是python中有關yield用法方面的總結,如有不對的地方或者不全面的地方歡迎大家批評指正!!!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM