2026/3/25 6:27:29
网站建设
项目流程
个人网站需要备案吗,天津市城市建设档案馆网站,wordpress数据量大网站访问,陕西省建设厅八大员证Python 中的观察者模式#xff08;Observer Pattern#xff09;
观察者模式是一种行为型设计模式#xff0c;其核心目的是#xff1a; 定义对象间的一种一对多依赖关系#xff0c;当一个对象#xff08;主题/被观察者#xff09;的状态发生改变时#xff0c;所有依赖它…Python 中的观察者模式Observer Pattern观察者模式是一种行为型设计模式其核心目的是定义对象间的一种一对多依赖关系当一个对象主题/被观察者的状态发生改变时所有依赖它的对象观察者都得到通知并自动更新。形象比喻就像订阅报纸——你观察者订阅了报纸主题每当有新报纸出版邮递员就会自动送到你家。观察者模式的优点实现主题和观察者之间的松耦合主题只知道观察者列表不关心具体类型支持广播通信一个变化通知多个对象符合“开闭原则”新增观察者无需修改主题代码典型应用场景GUI 系统按钮点击通知多个监听器事件驱动编程如 tkinter、PyQt 的信号槽发布-订阅系统消息队列、事件总线数据变更通知如股票价格更新、天气预报MVC 架构中的 View 更新Python 实现示例股票价格监控fromabcimportABC,abstractmethodfromtypingimportList# 观察者接口ObserverclassObserver(ABC):abstractmethoddefupdate(self,subject):pass# 具体观察者图表显示classChartDisplay(Observer):defupdate(self,subject):print(f【图表】股票价格更新{subject.stock_name} ${subject.price:.2f})# 具体观察者短信通知classSMSAlert(Observer):def__init__(self,phone_number:str):self.phone_numberphone_numberdefupdate(self,subject):ifsubject.price150:# 价格超过150时才发短信print(f【短信】发送到{self.phone_number}{subject.stock_name}已突破 ${subject.price:.2f}!)# 具体观察者邮件通知classEmailAlert(Observer):def__init__(self,email:str):self.emailemaildefupdate(self,subject):print(f【邮件】发送到{self.email}{subject.stock_name}最新价格 ${subject.price:.2f})# 主题Subject / ObservableclassStock:def__init__(self,name:str,price:float):self.stock_namename self.priceprice self._observers:List[Observer][]defattach(self,observer:Observer):ifobservernotinself._observers:self._observers.append(observer)print(f{observer.__class__.__name__}已订阅{self.stock_name})defdetach(self,observer:Observer):ifobserverinself._observers:self._observers.remove(observer)print(f{observer.__class__.__name__}已取消订阅{self.stock_name})defnotify(self):print(f通知所有观察者...)forobserverinself._observers:observer.update(self)defset_price(self,new_price:float):ifnew_price!self.price:self.pricenew_priceprint(f{self.stock_name}价格变动 → ${new_price:.2f})self.notify()# 客户端使用if__name____main__:# 创建股票主题apple_stockStock(AAPL,145.0)# 创建观察者chartChartDisplay()smsSMSAlert(138-1234-5678)emailEmailAlert(investorexample.com)# 订阅apple_stock.attach(chart)apple_stock.attach(sms)apple_stock.attach(email)print(\n--- 第一次价格更新 ---)apple_stock.set_price(152.0)# 触发通知print(\n--- 第二次价格更新 ---)apple_stock.set_price(148.0)# 短信不触发未超150print(\n--- 取消短信订阅 ---)apple_stock.detach(sms)print(\n--- 第三次价格更新 ---)apple_stock.set_price(160.0)# 只有图表和邮件收到通知输出ChartDisplay 已订阅 AAPL SMSAlert 已订阅 AAPL EmailAlert 已订阅 AAPL --- 第一次价格更新 --- AAPL 价格变动 → $152.00 通知所有观察者... 【图表】股票价格更新AAPL $152.00 【短信】发送到 138-1234-5678AAPL 已突破 $152.00! 【邮件】发送到 investorexample.comAAPL 最新价格 $152.00 --- 第二次价格更新 --- AAPL 价格变动 → $148.00 通知所有观察者... 【图表】股票价格更新AAPL $148.00 【邮件】发送到 investorexample.comAAPL 最新价格 $148.00 --- 取消短信订阅 --- SMSAlert 已取消订阅 AAPL --- 第三次价格更新 --- AAPL 价格变动 → $160.00 通知所有观察者... 【图表】股票价格更新AAPL $160.00 【邮件】发送到 investorexample.comAAPL 最新价格 $160.00Pythonic 更简洁实现使用属性装饰器Python 中可以用property实现自动通知classObservable:def__init__(self):self._observers[]defattach(self,observer):self._observers.append(observer)defdetach(self,observer):self._observers.remove(observer)defnotify(self):forobserverinself._observers:observer(self)# 直接传整个对象classStock(Observable):def__init__(self,name,price):super().__init__()self._namename self._pricepricepropertydefprice(self):returnself._priceprice.setterdefprice(self,value):self._pricevalue self.notify()# 自动通知# 使用stockStock(TSLA,800)stock.attach(lambdas:print(f价格更新:{s._name} ${s._price}))stock.price850# 自动触发内置支持事件库Python 标准库没有内置观察者但第三方库很成熟blinker轻量级信号系统PyDispatcher经典事件分发GUI 框架如tkinter、PyQt、PySide自带信号槽机制观察者模式结构总结角色说明Subject主题维护观察者列表提供 attach/detach/notifyObserver抽象观察者定义 update 接口ConcreteSubject具体主题如 Stock状态变化时调用 notifyConcreteObserver具体观察者如 ChartDisplay、SMSAlert观察者模式 vs 发布-订阅模式观察者模式主题直接持有观察者引用紧耦合于同一进程发布-订阅Pub/Sub通过消息中间件解耦支持分布式如 Redis、KafkaPython 中的实用建议小型项目手写观察者如上例中型项目使用property 回调列表GUI/事件驱动直接用框架的信号机制大型/分布式使用消息队列Celery、RabbitMQ注意事项通知顺序不确定除非显式排序避免在 update 中修改主题状态可能无限循环多线程时需加锁保护观察者列表取消订阅很重要避免内存泄漏观察者模式是事件驱动编程的核心在 Python 的 GUI、Web 框架、异步系统中无处不在。如果你想看更高级的例子如多线程安全观察者、结合 asyncio 的异步通知、使用 blinker 库的信号系统或者与其他模式结合如观察者 策略随时告诉我