在 Python 中实现观察者模式的具体步骤是什么?

在 Python 中实现观察者模式可以遵循以下具体步骤,这些步骤清晰地划分了角色和交互流程:

步骤 1:定义主题(Subject)基类

主题是被观察的对象,负责管理观察者和发送通知。需实现以下核心方法:

  • 存储观察者的容器(如列表)
  • 添加观察者的方法(attach
  • 移除观察者的方法(detach
  • 通知所有观察者的方法(notify
python 复制代码
class Subject:
    def __init__(self):
        self._observers = []  # 保存所有注册的观察者

    def attach(self, observer):
        """添加观察者到列表"""
        if observer not in self._observers:
            self._observers.append(observer)

    def detach(self, observer):
        """从列表中移除观察者"""
        try:
            self._observers.remove(observer)
        except ValueError:
            pass  # 忽略未找到的观察者

    def notify(self, *args, **kwargs):
        """通知所有观察者状态变化"""
        for observer in self._observers:
            observer.update(*args, **kwargs)  # 调用观察者的更新方法

步骤 2:实现具体主题(ConcreteSubject)

具体主题是实际业务对象,维护自身状态,当状态变化时触发通知。

python 复制代码
class WeatherStation(Subject):  # 继承主题基类
    def __init__(self):
        super().__init__()
        self._temperature = None  # 示例:温度状态

    @property
    def temperature(self):
        return self._temperature

    @temperature.setter
    def temperature(self, new_temp):
        self._temperature = new_temp  # 更新状态
        self.notify(new_temp)  # 状态变化时通知观察者

步骤 3:定义观察者(Observer)基类/接口

观察者是接收通知的对象,需定义一个更新方法(update),供主题调用。

python 复制代码
class Observer:
    def update(self, *args, **kwargs):
        """接收主题通知的方法,子类必须实现"""
        raise NotImplementedError("子类必须重写 update 方法")

步骤 4:实现具体观察者(ConcreteObserver)

具体观察者根据自身需求实现update方法,处理主题发送的通知。

python 复制代码
class PhoneDisplay(Observer):  # 手机显示屏观察者
    def update(self, temp):
        print(f"手机显示:当前温度 {temp}°C")

class WindowDisplay(Observer):  # 窗口显示屏观察者
    def update(self, temp):
        print(f"窗口显示:温度更新为 {temp}°C")

步骤 5:使用观察者模式

创建主题和观察者实例,关联它们,并触发状态变化验证效果。

python 复制代码
# 1. 创建主题(被观察者)
weather_station = WeatherStation()

# 2. 创建观察者
phone_display = PhoneDisplay()
window_display = WindowDisplay()

# 3. 注册观察者到主题
weather_station.attach(phone_display)
weather_station.attach(window_display)

# 4. 改变主题状态(自动通知观察者)
print("--- 温度变为 25°C ---")
weather_station.temperature = 25

print("\n--- 温度变为 30°C ---")
weather_station.temperature = 30

# 5. 移除一个观察者
weather_station.detach(phone_display)
print("\n--- 移除手机显示后,温度变为 28°C ---")
weather_station.temperature = 28

执行结果

复制代码
--- 温度变为 25°C ---
手机显示:当前温度 25°C
窗口显示:温度更新为 25°C

--- 温度变为 30°C ---
手机显示:当前温度 30°C
窗口显示:温度更新为 30°C

--- 移除手机显示后,温度变为 28°C ---
窗口显示:温度更新为 28°C

核心逻辑总结

  1. 主题与观察者解耦 :主题只需知道观察者有update方法,无需了解其具体实现;观察者也无需知道主题的内部逻辑。
  2. 动态关联 :通过attachdetach可以随时添加/移除观察者,灵活性高。
  3. 自动通知 :主题状态变化时,主动调用所有注册观察者的update方法,实现"一处变化,多处响应"。

这种模式适用于事件监听、状态同步、发布-订阅系统等场景,例如 GUI 中的按钮点击事件、数据更新通知等。

相关推荐
知远同学7 小时前
Anaconda的安装使用(为python管理虚拟环境)
开发语言·python
小徐Chao努力7 小时前
【Langchain4j-Java AI开发】09-Agent智能体工作流
java·开发语言·人工智能
Blossom.1187 小时前
AI编译器实战:从零手写算子融合与自动调度系统
人工智能·python·深度学习·机器学习·flask·transformer·tornado
CoderCodingNo7 小时前
【GESP】C++五级真题(贪心和剪枝思想) luogu-B3930 [GESP202312 五级] 烹饪问题
开发语言·c++·剪枝
kylezhao20197 小时前
第1章:第一节 开发环境搭建(工控场景最优配置)
开发语言·c#
啃火龙果的兔子7 小时前
JavaScript 中的 Symbol 特性详解
开发语言·javascript·ecmascript
热爱专研AI的学妹8 小时前
数眼搜索API与博查技术特性深度对比:实时性与数据完整性的核心差异
大数据·开发语言·数据库·人工智能·python
Mr_Chenph8 小时前
Miniconda3在Windows11上和本地Python共生
开发语言·python·miniconda3
阿狸远翔8 小时前
Protobuf 和 protoc-gen-go 详解
开发语言·后端·golang
永远前进不waiting8 小时前
C复习——1
c语言·开发语言