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

相关推荐
Python私教1 分钟前
请求超时不等于失败:把写操作恢复设计成事实回读
后端·python
goldbin_zhang_xu5 分钟前
我用 Go 重写了一个 OpenClaw 框架:这就是 GoClaw
开发语言·后端·golang·agent框架·goclaw·双循环机制
lingran__5 分钟前
C++ STL map 与 set 底层剖析与模拟实现万字详解|基于红黑树,复刻 SGI-STL 泛型复用架构
开发语言·c++·stl·set·map·泛型编程·sgi-stl
野生技术架构师6 分钟前
Multi-agent的新趋势,从Agent Team到Agent Swarm
开发语言·人工智能
且听风吟02208 分钟前
7.包管理工具
python
Bonnie_12159 分钟前
10-深入理解ConcurrentHashMap(JDK1.8)
java·开发语言
程序员杰哥35 分钟前
依赖于第三方接口时,如何进行测试?
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·接口测试
java修仙传36 分钟前
从网页禅道到 AI 能调用的工具:我的禅道 MCP 实现思路分享
java·人工智能·python·ai应用·mcp开发
reasonsummer38 分钟前
【办公类-120-01】20260812闵行区幼儿园概况表的数据统计(户籍、五类性质、优抚子女)
前端·python
宿67441 分钟前
vue3-指令和事件处理
开发语言·前端·javascript