一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務器之家 - 腳本之家 - Python - 一日一技:在 Python 中實現(xiàn)延遲調(diào)用

一日一技:在 Python 中實現(xiàn)延遲調(diào)用

2021-07-28 00:48未聞Codekingname Python

熟悉 Golang 的同學都知道,Golang 里面有一個關(guān)鍵詞叫做defer,它可以實現(xiàn)延遲調(diào)用。實際上在 Python 里面也有相關(guān)的語法,那就是contextlib.ExitStack。

一日一技:在 Python 中實現(xiàn)延遲調(diào)用

熟悉 Golang 的同學都知道,Golang 里面有一個關(guān)鍵詞叫做defer,它可以實現(xiàn)延遲調(diào)用。

實際上在 Python 里面也有相關(guān)的語法,那就是contextlib.ExitStack。

我們來看這樣一個場景:

我有一個函數(shù)parse,它的作用是從 Redis 中持續(xù)讀入數(shù)據(jù),并寫入到MongoDB 中。示例代碼如下:

  1. import json 
  2. import redis 
  3. import pymongo 
  4.  
  5. client = redis.Redis() 
  6. handler = pymongo.MongoClient().test.data 
  7.  
  8. def parse(): 
  9.     data = client.lpop('test'
  10.     if not data: 
  11.         return 
  12.     handler.insert_one(json.loads(data)) 

但現(xiàn)在我想增加一個需求,當Redis 讀取結(jié)束或者讀取數(shù)據(jù)報錯的時候,能把當前的時間也寫入到MongoDB 中。

那么代碼可能變成下面這樣:

  1. import json 
  2. import redis 
  3. import datetime 
  4. import pymongo 
  5.  
  6. client = redis.Redis() 
  7. handler = pymongo.MongoClient().test.data 
  8.  
  9. def parse(): 
  10.     while True
  11.         try: 
  12.             data = client.lpop('test'
  13.             if not data: 
  14.                 handler.insert_one({'finished'True'ts': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}) 
  15.                 return 
  16.             handler.insert_one(json.loads(data)) 
  17.         except Exception: 
  18.             handler.insert_one({'finished'True'ts': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'}) 

可以看到,代碼變得很難看了。

現(xiàn)在,我們可以使用延遲調(diào)用來讓代碼變得更好看。

要實現(xiàn)這個目的,就可以開始使用ExitStack了。它可以注冊多個回調(diào)函數(shù),在退出上下文縮進時執(zhí)行。

我們先來看一個簡單的例子:

  1. import contextlib 
  2.  
  3. def callback_1(): 
  4.     print('我是第一個回調(diào)函數(shù)'
  5.  
  6. def callback_2(x): 
  7.     print(f'我是第二個回調(diào)函數(shù),傳入?yún)?shù):{x}'
  8.  
  9.  
  10. with contextlib.ExitStack() as stack: 
  11.     stack.callback(callback_1) 
  12.     stack.callback(callback_2, 100) 
  13.     print(12345) 
  14.     print('xxxx'
  15. print('退出縮進'

運行效果如下圖所示:

一日一技:在 Python 中實現(xiàn)延遲調(diào)用

可以看出以下特點:

  1. 被添加的回調(diào)函數(shù)進入了一個棧,所以后添加的回調(diào)函數(shù)先調(diào)用
  2. 回調(diào)函數(shù)會在結(jié)束縮進的時候被調(diào)用

現(xiàn)在我們來人工構(gòu)造一個異常:

一日一技:在 Python 中實現(xiàn)延遲調(diào)用

可以看到,即使縮進里面出現(xiàn)了報錯,回調(diào)函數(shù)仍然可以正常運行。等所有回調(diào)函數(shù)運行完成以后,Python 才會退出。

基于以上特點,我們就可以來重構(gòu)最開始的代碼了:

  1. import json 
  2. import redis 
  3. import datetime 
  4. import pymongo 
  5. import contextlib 
  6.  
  7. client = redis.Redis() 
  8. handler = pymongo.MongoClient().test.data 
  9.  
  10. def add_ts(): 
  11.     handler.insert_one({'finished'True'ts': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}) 
  12.  
  13. def parse(): 
  14.     with contextlib.ExitStack() as stack: 
  15.         stack.callback(add_ts) 
  16.         while True
  17.             data = client.lpop('test'
  18.             if not data: 
  19.                 return 
  20.             handler.insert_one(json.loads(data)) 

無論是正常運行結(jié)束還是運行過程中報錯,add_ts函數(shù)都會正常運行,確保始終增加一條日期數(shù)據(jù)。

原文鏈接:https://mp.weixin.qq.com/s/fjbOA0YFW1jrsthtNem5aQ

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产成人综合亚洲亚洲欧美 | 人与蛇boxxⅹ | 暖暖中国免费观看高清完整版 | 男人猛激烈吃奶gif动态图 | 亚洲网站在线观看 | 亚洲美洲国产日产 | 色老板在线视频 | 丁香五香天堂网 | 日本高清免费中文字幕不卡 | 99re在线视频免费观看 | 九九精品免费视频 | 国产成人综合亚洲亚洲欧美 | 国产精品视频视频久久 | 国内精品露脸在线视频播放 | 4455在线 | 国产精品女主播自在线拍 | 岛国片免费观看 | 国产成人91高清精品免费 | 午夜片无码区在线观看 | 操老逼 | xxxx俄罗斯大白屁股 | 韩国美女豪爽一级毛片 | 国产亚洲精品精品国产亚洲综合 | 久久99视热频国只有精品 | 亚洲国产日韩制服在线观看 | 日本网络视频www色高清免费 | 色呦呦在线免费观看 | 精品国产成a人在线观看 | 久久毛片基地 | 小早川怜子在线播放精品 | 日本伊人色综合网 | 扒开女人下面使劲桶屁股动漫 | 国产精品酒店视频免费看 | 日本在线一区二区 | 果冻传媒天美传媒在线小视频播放 | 青草欧美 | 色人阁导航 | 男人爱看的网站 | 高h视频免费观看 | ai换脸杨颖啪啪免费网站 | 国产精品密播放国产免费看 |