自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

[[413590]]

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

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

我們來看這樣一個(gè)場景:

我有一個(gè)函數(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)在我想增加一個(gè)需求,當(dāng)Redis 讀取結(jié)束或者讀取數(shù)據(jù)報(bào)錯(cuò)的時(shí)候,能把當(dāng)前的時(shí)間也寫入到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)用來讓代碼變得更好看。

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

我們先來看一個(gè)簡單的例子:

  1. import contextlib 
  2.  
  3. def callback_1(): 
  4.     print('我是第一個(gè)回調(diào)函數(shù)'
  5.  
  6. def callback_2(x): 
  7.     print(f'我是第二個(gè)回調(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('退出縮進(jìn)'

運(yùn)行效果如下圖所示:

可以看出以下特點(diǎn):

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

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

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

基于以上特點(diǎn),我們就可以來重構(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)) 

 

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

本文轉(zhuǎn)載自微信公眾號(hào)「未聞Code」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系未聞Code公眾號(hào)。

 

責(zé)任編輯:武曉燕 來源: 未聞Code
相關(guān)推薦

2021-03-12 21:19:15

Python鏈?zhǔn)?/a>調(diào)用

2021-09-13 20:38:47

Python鏈?zhǔn)?/a>調(diào)用

2024-02-20 22:13:48

Python項(xiàng)目Java

2021-04-12 21:19:01

PythonMakefile項(xiàng)目

2022-06-28 09:31:44

LinuxmacOS系統(tǒng)

2021-06-08 21:36:24

PyCharm爬蟲Scrapy

2024-11-11 00:38:13

Mypy靜態(tài)類型

2022-03-12 20:38:14

網(wǎng)頁Python測試

2021-04-05 14:47:55

Python多線程事件監(jiān)控

2024-11-13 09:18:09

2024-07-30 08:11:16

2024-07-30 08:16:18

Python代碼工具

2021-10-06 23:17:26

Python抽象類接口

2024-10-16 21:47:15

2021-10-15 21:08:31

PandasExcel對象

2021-04-27 22:15:02

Selenium瀏覽器爬蟲

2020-12-11 06:30:00

工具分組DataFrame

2021-05-12 00:12:37

Ocelot網(wǎng)關(guān)密碼

2021-09-14 10:48:33

Ocelot網(wǎng)關(guān)

2020-05-19 13:55:38

Python加密密碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)