日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python3 yield 大文件_详解Python3中yield生成器的用法

發(fā)布時(shí)間:2024/9/19 python 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python3 yield 大文件_详解Python3中yield生成器的用法 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

任何使用yield的函數(shù)都稱之為生成器,如:

def count(n):

while n > 0:

yield n #生成值:n

n -= 1

另外一種說法:生成器就是一個(gè)返回迭代器的函數(shù),與普通函數(shù)的區(qū)別是生成器包含yield語句,更簡單點(diǎn)理解生成器就是一個(gè)迭代器。

使用yield,可以讓函數(shù)生成一個(gè)序列,該函數(shù)返回的對象類型是"generator",通過該對象連續(xù)調(diào)用next()方法返回序列值。

c = count(5)

c.__next__() #python 3.4.3要使用c.__next__()不能使用c.next()

>>> 5

c.__next__()

>>>4

生成器函數(shù)只有在調(diào)用__next()__方法的時(shí)候才開始執(zhí)行函數(shù)里面的語句,比如:

def count(n):

print ( "cunting" )

while n > 0:

yield n #生成值:n

n -= 1

在調(diào)用count函數(shù)時(shí):c=count(5),并不會(huì)打印"counting"只有等到調(diào)用c.__next__()時(shí)才真正執(zhí)行里面的語句。每次調(diào)用__next__()方法時(shí),count函數(shù)會(huì)運(yùn)行到語句yield n處為止,__next__()的返回值就是生成值n,再次調(diào)用__next__()方法時(shí),函數(shù)繼續(xù)執(zhí)行yield之后的語句(熟悉Java的朋友肯定知道Thread.yield()方法,作用是暫停當(dāng)前線程的運(yùn)行,讓其他線程執(zhí)行),如:

def count(n):

print ("cunting" )

while n > 0:

print ('before yield')

yield n #生成值:n

n -= 1

print ('after yield' )

上述代碼在第一次調(diào)用__next__方法時(shí),并不會(huì)打印"after yield"。如果一直調(diào)用__next__方法,當(dāng)執(zhí)行到?jīng)]有可迭代的值后,程序就會(huì)報(bào)錯(cuò):

Traceback (most recent call last): File "", line 1, in StopIteration

所以一般不會(huì)手動(dòng)的調(diào)用__next__方法,而使用for循環(huán):

for i in count(5):

print (i),

實(shí)例: 用yield生成器模擬Linux中命令:tail -f file | grep python 用于查找監(jiān)控日志文件中出現(xiàn)有python字樣的行。

import time

def tail(f):

f.seek(0,2)#移動(dòng)到文件EOF

while True:

line = f.readline() #讀取文件中新的文本行

if not line:

time.sleep(0.1)

continue

yield line

def grep(lines,searchtext):

for line in lines:

if searchtext in line:

yield line

flog = tail(open('warn.log'))

pylines = grep(flog,'python')

for line in pylines:

print ( line, )

#當(dāng)此程序運(yùn)行時(shí),若warn.log文件中末尾有新增一行,且該一行包含python,該行就會(huì)被打印出來

#若打開warn.log時(shí),末尾已經(jīng)有了一行包含python,該行不會(huì)被打印,因?yàn)樯厦媸莊.seek(0,2)移動(dòng)到了文件EOF處

#故,上面程序?qū)崿F(xiàn)了tail -f warn.log | grep 'python'的功能,動(dòng)態(tài)實(shí)時(shí)檢測warn.log中是否新增現(xiàn)了

#新的行,且該行包含python

用yield實(shí)現(xiàn)斐波那契數(shù)列:

def fibonacci():

a=b=1

yield a

yield b

while True:

a,b = b,a+b

yield b

調(diào)用:

for num in fibonacci():

if num > 100:

break

print (num),

yield中return的作用:

作為生成器,因?yàn)槊看蔚蜁?huì)返回一個(gè)值,所以不能顯示的在生成器函數(shù)中return 某個(gè)值,包括None值也不行,否則會(huì)拋出“SyntaxError”的異常,但是在函數(shù)中可以出現(xiàn)單獨(dú)的return,表示結(jié)束該語句。

通過固定長度的緩沖區(qū)不斷讀文件,防止一次性讀取出現(xiàn)內(nèi)存溢出的例子:

def read_file(path):

size = 1024

with open(path,'r') as f:

while True:

block = f.read(SIZE)

if block:

yield block

else:

return

如果是在函數(shù)中return 具體某個(gè)值,就直接拋異常了

>>> def test_return():

... yield 4

... return 0

...

File "", line 3

SyntaxError: 'return' with argument inside generator

例子

下面來看幾段代碼示例:

例1:

>>> def mygenerator():

... print 'start...'

... yield 5

...

>>> mygenerator() //在此處調(diào)用,并沒有打印出start...說明存在yield的函數(shù)沒有被運(yùn)行,即暫停

>>> mygenerator().next() //調(diào)用next()即可讓函數(shù)運(yùn)行.

start...

5

>>>

如一個(gè)函數(shù)中出現(xiàn)多個(gè)yield則next()會(huì)停止在下一個(gè)yield前,見例2:

例2:

>>> def fun2():

... print 'first'

... yield 5

... print 'second'

... yield 23

... print 'end...'

...

>>> g1 = fun2()

>>> g1.next() //第一次運(yùn)行,暫停在yield 5

first

5

>>> g1.next() //第二次運(yùn)行,暫停在yield 23

second

23

>>> g1.next() //第三次運(yùn)行,由于之后沒有yield,再次next()就會(huì)拋出錯(cuò)誤

end...

Traceback (most recent call last):

File "", line 1, in

StopIteration

>>>

為什么yield 5會(huì)輸出5,yield 23會(huì)輸出23?

我們猜測可能是因?yàn)閥ield是表達(dá)式,存在返回值.

那么這是否可以認(rèn)為yield 5的返回值一定是5嗎?實(shí)際上并不是這樣,這個(gè)與send函數(shù)存在一定的關(guān)系,這個(gè)函數(shù)實(shí)質(zhì)上與next()是相似的,區(qū)別是send是傳遞yield表達(dá)式的值進(jìn)去,而next不能傳遞特定的值,只能傳遞None進(jìn)去,因此可以認(rèn)為g.next()和g.send(None)是相同的。見例3:

例3:

>>> def fun():

... print 'start...'

... m = yield 5

... print m

... print 'middle...'

... d = yield 12

... print d

... print 'end...'

...

>>> m = fun() //創(chuàng)建一個(gè)對象

>>> m.next() //會(huì)使函數(shù)執(zhí)行到下一個(gè)yield前

start...

5

>>> m.send('message') //利用send()傳遞值

message //send()傳遞進(jìn)來的

middle...

12

>>> m.next()

None //可見next()返回值為空

end...

Traceback (most recent call last):

File "", line 1, in

StopIteration

本文標(biāo)題: 詳解Python3中yield生成器的用法

本文地址: http://www.cppcns.com/jiaoben/python/129931.html

總結(jié)

以上是生活随笔為你收集整理的python3 yield 大文件_详解Python3中yield生成器的用法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。