<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
觀察者模式:是一種行為型設計模式。主要關注的是物件的責任,允許你定義一種訂閱機制,可在物件事件發生時通知多個"觀察"該物件的其他物件。用來處理物件之間彼此互動。
觀察者模式也叫釋出-訂閱模式,定義了物件之間一對多依賴,當一個物件改變狀態時,這個物件的所有依賴者都會收到通知並按照自己的方式進行更新。
觀察者設計模式是最簡單的行為模式之一。在觀察者設計模式中,物件維護了一個依賴(觀察者)列表,以便主題可以使用觀察者定義的任何方法通知所有觀察者它所發生的變化。
可使用觀察者模式應用場景
在廣播或者釋出訂閱系統的情形中,你會看到觀察者設計模式的用法,它的主要使用場景如下:
1、分散式系統中實現事件服務。
2、廣播或釋出/閱系統情形中。
2、用作新聞機器的框架。
3、股票監測機器人。
觀察者模式類圖
1、釋出者Publisher:向其他物件傳送值得關注的事件。事件會在釋出者自身狀態改變或執行特定行為後發生。釋出者中包含一個允許新訂閱者加入和當前訂閱者離開列表的訂閱機制。
2、訂閱者Subscriber:定義通知介面。一般情況下,該介面僅包含一個update()更新方法。方法中可以有多個引數,使釋出者能在更新時傳遞事件詳細資訊。
3、使用者端Client:分別建立釋出者和訂閱者物件,然後為訂閱者註冊,釋出者更新。
假如我們對應用函數執行狀態進行監測,當發生異常時報警記錄,可通過觀察者模式進行資訊訂閱:1、簡訊 2、紀錄檔 3、郵件
程式碼實現---subscription_model.py
Subscriber訂閱者:所有希望關注釋出者狀態變化的其他物件。
這裡提供了三個主要的訂閱者(觀察者)介面,跟蹤著同一個釋出者類的事件。主要包括:
1)、每個具體訂閱者__init()方法使用attach()方法向釋出者進行註冊以獲取資訊更新。
2)、具體訂閱者的update()更新訊息。
#抽象訂閱者 from abc import ABCMeta,abstractmethod class Subscriber(metaclass=ABCMeta): #向具體訂閱者傳送訊息的方法 @abstractmethod def update(self): pass #具體訂閱者 #1、簡訊訂閱者 class SMSSubscriber(Subscriber): def __init__(self,publisher): self.publisher = publisher self.publisher.attach(self) def update(self): print(type(self).__name__,self.publisher.getNews()) #2、郵件訂閱者 class EmailSubscriber(Subscriber): def __init__(self, publisher): self.publisher = publisher self.publisher.attach(self) def update(self): print(type(self).__name__,self.publisher.getNews()) info = self.publisher.getNews() # 傳送郵件 Sender_mail(info).sender_mail() #3、紀錄檔訂閱(檔案儲存) class LoggerSubscriber(Subscriber): def __init__(self, publisher): log_dir = os.path.expanduser(r".appsMapviewlogs") log_file = os.path.join(log_dir, "file_{time}.log") logger.add(log_file, rotation="100KB", retention=2) self.publisher = publisher self.publisher.attach(self) def update(self): print(type(self).__name__,self.publisher.getNews()) info=self.publisher.getNews() logger.info(f"{info}")
Publisher釋出者:將自身的狀態改變通知其他物件,為釋出者新增訂閱機制,每個物件都能訂閱或取消訂閱者事件流。
主要包括:
1)self.__subscribers = []:一個用於儲存訂閱物件列表
2)供訂閱者來註冊NewsPublisher或刪除訂閱使用者。
3)幾個用於新增、刪除或檢視列表中訂閱者的公有方法。
4)notifySubscribers(self):用於通知所有訂閱者出現新的資訊,傳送者會遍歷訂閱列表並通過內部呼叫具體訂閱者實現的update()方法來實現。
5)建立新訊息和返回最新訊息。
#建立釋出者 class NewsPublisher: def __init__(self): self.__subscribers = [] self.__latestNews = None #將訂閱者新增到佇列中 def attach(self,subscriber): self.__subscribers.append(subscriber) #從訂閱的主題裡面移除 def detach(self): return self.__subscribers.pop() #生成觀察者列表 def subscribers(self): return [type(x).__name__ for x in self.__subscribers] #傳送通知給相關的主題訂閱者 def notifySubscribers(self): for sub in self.__subscribers: #update()方法由具體的觀察者或訂閱者實現的 sub.update() #推播更新 #建立新訊息 def addNews(self,news): self.__latestNews = news #返回最新訊息,並通知觀察者 def getNews(self): return "Got News:",self.__latestNews
訂閱者通常需要一些上下文資訊正確處理更新。因此,釋出者通常會將一些上下文資料作為通知方法的引數傳遞。
這裡給第一篇文章留下的尾巴補充一下,使用者端範例化get_Map_model方法新增帶引數裝飾器,@fail_data(msg='地圖載入失敗')新增介面呼叫失敗處理機制,追加紀錄檔記錄。這裡可以進一步將更多細節引數新增到紀錄檔中,裝飾器傳參並在介面中宣告通知方法及引數,這樣釋出者在發出通知時傳遞一些上下文資料。
from apps.tools.subscription_model import NewsPublisher,LoggerSubscriber,EmailSubscriber import functools #如果載入失敗,呼叫訂閱者 def publisher(info): news_publisher = NewsPublisher() # for Subscribers in [EmailSubscriber, LoggerSubscriber]: for Subscribers in [LoggerSubscriber]: # eval(LoggerSubscriber)(news_publisher) Subscribers(news_publisher) print("nSubscribers", news_publisher.subscribers()) news_publisher.addNews(f"{info}") news_publisher.notifySubscribers() #處理異常的裝飾器 def fail_data(msg='地圖載入失敗'): def catch_exception(origin_func): @functools.wraps(origin_func) def wrapper(*args, **kwargs): try: u = origin_func(*args, **kwargs) print("這個函數正常執行:%s" % origin_func.__name__) return u except Exception as e: info = f"{msg}:{e.__doc__}" """ 介面呼叫失敗處理機制,追加紀錄檔 """ print(info) publisher(info) # news_publisher = NewsPublisher() # LoggerSubscriber(news_publisher) # print("nSubscribers", news_publisher.subscribers()) # news_publisher.addNews(f"{info}") # news_publisher.notifySubscribers() return wrapper return catch_exception
if __name__ == '__main__': from loguru import logger from apps.tools.Sender_Email import Sender_mail news_publisher =NewsPublisher() for Subscribers in [LoggerSubscriber]: print(Subscribers) Subscribers(news_publisher) print("nSubscribers",news_publisher.subscribers()) news_publisher.addNews("地圖載入失敗!") news_publisher.notifySubscribers()
結果
class '__main__.LoggerSubscriber';
Subscribers ['LoggerSubscriber']
LoggerSubscriber ('Got News:', '地圖載入失敗!')
2022-04-05 16:38:00.667 | INFO | __main__:update:81 - ('Got News:', '地圖載入失敗!')
以上就是實現了一個簡單的釋出訂閱模式,釋出者與訂閱者之間是鬆耦合的,新增新訂閱者無需修改釋出者。所有具體訂閱者類都實現了同樣介面。
到此這篇關於Python實現紀錄檔實時監測的範例詳解的文章就介紹到這了,更多相關Python紀錄檔監測內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45