在 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 中的按钮点击事件、数据更新通知等。

相关推荐
叫我:松哥2 分钟前
基于Flask框架的校园二手书籍交易平台,注重校园场景的特殊需求,通过学号认证保障用户真实性
后端·python·sqlite·flask·bootstrap
namexingyun14 分钟前
开源前端生态如何成为 AI UI 生成的“燃料“:shadcn/ui、Tailwind CSS、Storybook 技术价值全解剖
java·前端·人工智能·python·ui·开源·ai编程
通信仿真爱好者18 分钟前
第【17】期--考虑硬件损伤和不完美CSI的RIS-MISO系统的深度强化学习联合优化-python完整代码+参考文献
python·深度强化学习·ris
装不满的克莱因瓶24 分钟前
自然语言处理常见任务——从文本理解到生成式AI的完整任务体系
人工智能·pytorch·python·深度学习·ai·自然语言处理
z落落28 分钟前
C#WinForm控件实战:Panel与单选框动态创建
开发语言·c#
ptc学习者28 分钟前
python 中描述符@property property 大概的样子
开发语言·python
zmzb010330 分钟前
Python课后习题训练记录Day129
开发语言·python
张忠琳38 分钟前
【Go 1.26.4】Golang Map 深度解析
开发语言·后端·golang
Vertira39 分钟前
如何对QT开发的软件进行打包[已解决]
开发语言·qt
AI人工智能+电脑小能手41 分钟前
【大白话说Java面试题 第110题】【并发篇】第10题:CAS 存在哪些问题?
java·开发语言·面试