標籤:none djang 執行個體 cab send 就會 並且 tor span
1 yield 在使用send, next時候的區別(舉例m = yield 5)
無論send,next首先理解m = yield 5 是將運算式"yield 5 "的結果返回給m, 而不是m=5這麼簡單, 所以涉及到如何擷取運算式yield 5的值,這就和next,send有關。
當send(arg)時,就會將arg 認為yield 5運算式的結果賦給m,而如果是next,就會將None作為yield 5運算式的結果付給m;
所以可認為next 等效於send(None),除了第一次next外
區別就是:
使用next()時,第一次next, 在遇到yield停止,並且將yield右邊的運算式“5”作為next函數的傳回值返回給外界; 之後的next,會將None作為yield 5運算式的值賦給m,
程式往下執行,遇到下一個yield時,將yield右邊的運算式5作為該次的next的傳回值
使用send(arg)時(前面必須已經使用了next), 將arg作為yield運算式"yield 5"的值,賦給m;程式往下執行,然後將下個yield的右邊運算式"5"作為send函數的傳回值
next例子:
def f(): print("start") current = yield "hello" print(‘current=‘, current) while True: value = yield "bad" # value = value + ‘not‘ # 此行會報錯,因為value會為None, 不能和字串進行相加g = f()s1 = next(g)print(‘s1=‘,s1)# 第一次Next時,停止在第5行, 將yield右邊的運算式(無即None)作為next()的傳回值s2 = next(g)print(‘s2=‘, s2)# 第二次的next,會將None作為yield運算式" yield hello"的值賦給current, 即current = None# 然後程式往下執行,遇到yield "bad"停止,將yield右邊的運算式"bad"作為第二次next的傳回值s3 = next(g)print(‘s3=‘,s3)# 第三次next,會將None作為yield運算式”yield bad"的值賦給value, 即value = None,# 程式往下執行,遇到value = yield "bad"停止,將"bad"作為第三次next的傳回值View Code
send例子:
def f(): print("start") current = yield "hello" print(‘current=‘, current) while True: value = yield "bad" print("value=",value) # value = value + ‘not‘ # 此行會報錯,因為value會為整形, 不能和字串進行相加g = f()s1 = next(g)# 這一步不能少# 第一次Next時,停止在第5行, 將yield右邊的運算式(無即None)作為next()的傳回值print(g.send(10))# 產生器調用第一次send時,將send參數10代替運算式"yield hello"的值,賦給current,# 然後程式往下執行,在遇到yield bad停止,將"bad"作為第一次send()函數的傳回值返給外界print(g.send(20))# 產生器第二次調用send時,將send參數20代替運算式"yield bad"賦給 value# 程式往下執行,然後遇到yield bad停止,將"bad"作為第二次send()函數的傳回值返給外界View Code
2 yield與產生器generator
函數裡面使用了yield不再是函數,而是一個產生器generator。 比如
def fab(max): n, a, b = 0, 0, 1 while n < max: yield b # print b a, b = b, a + b n = n + 1
當執行g = fab(5)時,不是調用函數,而是執行個體化一個產生器對象。 當迴圈g對象或者next(g)時才會調用fab函數裡面的代碼
def test(): # print(‘one‘) yield 1 # print(‘two‘) yield 2g = test()for i in g: print(i)# 應該和下面效果是一樣的:g = test()res = next(g)print(res)# 首次遇到next()會執行test代碼,並停留在yield 1 處,# 同時將yield 後面運算式的值作為next的傳回值返回給外界#res = next(g)print(res)# 接著上面儲存的地方,運行print two,# 碰到yield 2 ,停止並把後面的2作為Next的傳回值返回給外界
View Code
3 產生器是有狀態的,調用者不可反覆使用它。比如:
def test(): yield 1 yield 2g = test()for i in g: print(i)# 下面這裡是沒有效果的for i in g: print(‘hello‘) print(i)
View Code
[oldboy-django][4python面試]有關yield那些事