中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

Python 異步調(diào)用命令行工具

2018-07-20    來(lái)源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢(shì)上線(xiàn)!快速搭建集群,上萬(wàn)Linux鏡像隨意使用

當(dāng)你在自己的 Python 程序中采用了基于事件循環(huán)的異步編程方法之后,你就會(huì)發(fā)現(xiàn)自己不自覺(jué)地被其牢牢吸引住,并不是說(shuō)這一方法多么棒,而是因?yàn)槟悴坏貌幌朕k法保證程序中的任意環(huán)節(jié)都不能是阻塞的!

例如當(dāng)前的場(chǎng)景是希望從 MongoDB 中讀取每一條未處理過(guò)的數(shù)據(jù),下載并保存其中的圖片信息,然后更新數(shù)據(jù)庫(kù)的內(nèi)容。Python 常用的 MongoDB 異步驅(qū)動(dòng)是 Motor :

結(jié)合 asyncio 使用方法如下:

importmotor.motor_asyncio  
importasyncio
 
client = motor.motor_asyncio.AsyncIOMotorClient()  
db = client.test_database
 
asyncdefrun():  
    asyncfor mmin db.test_database.find({"status": 0}):
        print(mm['img_src'])
        # Download Image Here
        # dl_img(mm['img_src'])
 
        awaitdb.test_database.update({"_id": mm['_id']}, {"$set": {"status":1}})
 
loop = asyncio.get_event_loop()  
loop.run_until_complete(run())  

此時(shí)如果 dl_img() 處的操作是阻塞的,那么異步處理就沒(méi)有意義了。當(dāng)然這里依然可以借助異步網(wǎng)絡(luò)請(qǐng)求庫(kù) aiohttp 來(lái)實(shí)現(xiàn)圖片下載:

asyncwithsession.get(img) as resp:  
    withopen(img.split("/")[-1], 'wb') as fd:
        while True:
            chunk = awaitresp.content.read(1024)
            if not chunk:
                break
            fd.write(chunk)

當(dāng)然也可以不需要自己動(dòng)手下載,直接調(diào)用系統(tǒng)命令行工具(例如 wget )來(lái)完成下載任務(wù)。Python 通過(guò) subprocess 標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)系統(tǒng)命令調(diào)用(取代舊的 os.system(cmd) ),執(zhí)行下載任務(wù)只需要:

importsubprocessas sb
 
sb.run(['wget', img], shell=True)  

但是這種調(diào)用方式是無(wú)法直接在 asyncio 的事件循環(huán)中使用的,但是 asyncio 提供了對(duì)應(yīng)的 subprocess 接口 :

asyncio.create_subprocess_exec(*args, ...)  
asyncio.create_subprocess_shell(cmd, ...)  

這兩個(gè)方法均返回一個(gè) asyncio.subprocess.Process 實(shí)例,而它的接口設(shè)計(jì)完全模仿了 subprocess.Popen (上面提到 subprocess.run() 的底層實(shí)現(xiàn)),因此很容易將其用法移植到事件循環(huán)中:

asyncdefdl_img(src):  
    dl = awaitasyncio.create_subprocess_shell('wget {} -O {}'.format(src, src.split("/")[-1])
    awaitdl.wait()

除了上面場(chǎng)景中的用法,也可以直接將命令行的執(zhí)行作為任務(wù)放入事件循環(huán):

loop = asyncio.get_event_loop()  
sb = asyncio.create_subprocess_shell('exit 7', loop=loop)  
proc = loop.run_until_complete(sb)  
exitcode = loop.run_until_complete(proc.wait())  

小結(jié)

在 Python 異步編程的意義就在于不要讓 CPU 堵在 IO 上,因此需要在每一處涉及到阻塞的操作都需要注意使用正確的異步方法,而一旦這些操作被封裝成異步的 Task 之后,其后續(xù)的調(diào)度執(zhí)行就無(wú)需再顧慮了。

 

 

 

來(lái)自:http://python.jobbole.com/86829/

 

標(biāo)簽: 數(shù)據(jù)庫(kù) 網(wǎng)絡(luò)

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:Android里巧妙實(shí)現(xiàn)緩存

下一篇:iOS-自適應(yīng)總結(jié)