Python 面向对象(OOP)速成指南:从零开始打造你的“智能家居”

Python 面向对象(OOP)速成指南:从零开始打造你的“智能家居”

欢迎来到 Python 面向对象编程的世界!

如果你习惯了面向过程的“流水账”式写法,或者你是正在从 Java 痛苦(误)转型 Python 的工程师,这篇文章就是为你准备的。今天,我们不讲枯燥的理论,我们将化身架构师,用上帝视角打造一套智能家居系统


🏗️ 第一章:上帝的图纸 —— 类与对象

在 Python 中,一切皆对象。但对象从哪来?得先有图纸。

  • 类 (Class):就是图纸(或者模具)。
  • 对象 (Object):就是根据图纸造出来的实物(比如你家的那个具体的小爱同学)。

1.1 定义你的第一个设备

我们先定义一个最基础的电器类。

classSmartDevice:"""智能设备基类"""# 类变量:所有设备通用的标签(类似 Java 的 static) platform ="HarmonyOS Connect"def__init__(self, name:str, location:str):""" 构造方法(初始化大师) self 相当于 Java 的 this,代表"当前这个对象自己" """ self.name = name # 实例变量 self.location = location # 实例变量 self.is_on =False# 默认关闭defswitch(self):"""普通实例方法""" self.is_on =not self.is_on state ="开启"if self.is_on else"关闭"returnf"[{self.location}] 的 {self.name} 已{state}"def__str__(self):""" 魔术方法:相当于 Java 的 toString() 决定了 print(对象) 时显示什么 """returnf"<设备: {self.name} @ {self.location}>"# === 实战演练 === light = SmartDevice("米家台灯","书房")# 实例化print(light)# 自动调用 __str__print(light.switch())# 调用方法print(f"接入平台: {SmartDevice.platform}")# 访问类变量

💡 Java 工程师请注意:

  • 没有 new 关键字,直接 类名() 就行。
  • self 必须显式地写在方法的第一个参数里,但在调用时不需要传它。
  • 构造函数不叫类名,统一叫 __init__

🔐 第二章:不要乱动我的电线 —— 封装

在 Java 中我们习惯用 private 加上 get/set 方法。Python 比较“随性”,它没有真正的私有,主要靠君子协定

2.1 优雅的属性控制

假设我们要做一个“智能音箱”,音量不能调成负数吧?这时候就需要封装了。

classSmartSpeaker:def__init__(self, name): self.name = name self._volume =20# 单下划线:暗示这是受保护的(Protected),请别直接改 self.__firmware ="v1.0"# 双下划线:名称重整(Private),外部极难访问# @property 装饰器:让方法像属性一样被访问(Getter)@propertydefvolume(self):return self._volume # @volume.setter:对应的 [email protected](self, value):if0<= value <=100: self._volume = value print(f"🔊 音量已调节为: {self._volume}")else:print("❌ 音量设置无效!必须在 0-100 之间")# === 实战演练 === speaker = SmartSpeaker("小爱同学") speaker.volume =150# 触发 setter 校验,报错 speaker.volume =80# 成功print(f"当前音量: {speaker.volume}")# 像访问变量一样访问方法# print(speaker.__firmware) # 报错!私有属性无法访问

🚀 核心知识点:

  • _var: “兄弟,别改这个,后果自负。”
  • __var: “这个你真改不了(除非你用特殊手段)。”
  • @property: 告别丑陋的 setVolume(10),回归优雅的 speaker.volume = 10

👨‍👩‍👦 第三章:家族传承 —— 继承与多态

智能家居里有很多设备,它们都有开关功能,但具体功能不同。比如灯能调亮度,空调能调温度。我们不需要把开关逻辑写两遍。

3.1 子承父业

# 继承自 SmartDeviceclassSmartLight(SmartDevice):def__init__(self, name, location, brightness=100):# super() 相当于 Java 的 super,调用父类初始化super().__init__(name, location) self.brightness = brightness # 方法重写 (Override):无需注解,直接覆盖defswitch(self): original_msg =super().switch()#以此保留父类逻辑returnf"{original_msg},当前亮度 ✨ {self.brightness}%"defset_color(self, color):returnf"{self.name} 变更为氛围光: {color}"# 另一个子类classAirConditioner(SmartDevice):defadjust_temp(self, temp):returnf"{self.name} 温度设定为 ❄️ {temp}°C"# === 多态演示 === devices =[ SmartLight("吸顶灯","客厅"), AirConditioner("立式空调","客厅")]for dev in devices:print(dev.switch())# 同样的 switch,不同的表现

⚡ 第四章:懒人神器 —— 数据类 (Dataclasses)

在 Java 中你可能用过 Lombok 的 @Data。Python 3.7+ 也有类似的黑科技:@dataclass。它能自动帮你写好 __init____str__ 等方法。

这非常适合用来定义单纯传输数据的对象,比如传感器数据。

from dataclasses import dataclass @dataclassclassSensorData: timestamp:str temperature:float humidity:float battery:int=100# 默认值# 直接创建,无需手写 __init__ data = SensorData("2023-10-01 12:00",26.5,45.0)print(data)# 输出: SensorData(timestamp='2023-10-01 12:00', temperature=26.5, humidity=45.0, battery=100)

🛠️ 实战项目:打造全屋智能中控系统

现在,我们将前面的知识点串联起来,编写一个智能中控中心 (SmartHub)。我们将引入一点“智能体 (Agent)”的设计模式,让它看起来更聪明。

项目需求

  1. 有一个中控 Hub,管理所有设备。
  2. 支持注册设备、移除设备。
  3. 具备“一键回家模式”:打开所有灯,打开空调。
  4. 具备简单的命令解析能力。

完整代码实现

from typing import List, Dict # 1. 定义抽象基类 (类似 Java Interface/Abstract Class)# 强制子类必须实现 execute_command 方法classIOTDevice:defexecute_command(self, cmd:str)->str:raise NotImplementedError("子类必须实现此方法")# 2. 具体设备实现classSmartLight(IOTDevice):def__init__(self, name): self.name = name self.is_on =Falsedefexecute_command(self, cmd:str)->str:if cmd =="on": self.is_on =Truereturnf"💡 {self.name} 已点亮"elif cmd =="off": self.is_on =Falsereturnf"🌑 {self.name} 已熄灭"returnf"{self.name} 无法识别指令"classSmartSpeaker(IOTDevice):def__init__(self, name): self.name = name defexecute_command(self, cmd:str)->str:if cmd.startswith("play"): song = cmd.split(" ")[1]returnf"🎵 {self.name} 正在播放: {song}"return"🔇 静默中"# 3. 智能中控 (核心逻辑)classSmartHomeHub:"""智能家居中控系统"""def__init__(self, home_name:str): self.home_name = home_name # 使用字典存储设备:{ "device_id": DeviceObj } self._devices: Dict[str, IOTDevice]={}defadd_device(self, dev_id:str, device: IOTDevice): self._devices[dev_id]= device print(f"✅ [系统] 设备 {dev_id} 已接入 {self.home_name}")defvoice_command(self, command:str):"""简单的自然语言指令解析"""print(f"\n🗣️ 收到指令: '{command}'")if"回家"in command: self._activate_scene("home")elif"睡觉"in command: self._activate_scene("sleep")else:print("🤖 抱歉,我没听懂,请重试。")def_activate_scene(self, scene_name:str):"""场景模式 (私有方法)"""print(f"--- 正在执行场景: {scene_name} ---")if scene_name =="home":# 批量操作:鸭子类型 (Duck Typing)# 只要设备有 execute_command 方法,管它是什么类,直接调!for dev_id, dev in self._devices.items():ifisinstance(dev, SmartLight):print(dev.execute_command("on"))elifisinstance(dev, SmartSpeaker):print(dev.execute_command("play Welcome_Home_Music"))elif scene_name =="sleep":for dev in self._devices.values():# 尝试关闭所有能关闭的东西print(dev.execute_command("off"))print("------------------------------")# ==========================================# 🚀 启动你的智能家居# ==========================================# 1. 创建中控 my_home = SmartHomeHub("钢铁侠的海景房")# 2. 购买设备 living_room_light = SmartLight("客厅主灯") bedroom_light = SmartLight("卧室氛围灯") jarvis = SmartSpeaker("贾维斯音箱")# 3. 联网 my_home.add_device("light_001", living_room_light) my_home.add_device("light_002", bedroom_light) my_home.add_device("speaker_001", jarvis)# 4. 测试语音控制 my_home.voice_command("我回家了")# 预期:灯亮,音乐响 my_home.voice_command("我要睡觉了")# 预期:灯灭

📝 总结

恭喜你!你已经掌握了 Python 面向对象的核心:

  1. 类与对象:蓝图与实体。
  2. 封装:用 @property 保护数据。
  3. 继承:复用代码,拒绝重复。
  4. 多态/鸭子类型:关注它能做什么(方法),而不是它是什么。

下一步你可以做什么?

  • 尝试给 SmartHomeHub 增加一个 remove_device 方法。
  • 利用 Python 的 json 模块,把设备状态保存到文件里,重启后还能记住灯是开着的(这是持久化的第一步)。

去创造你的世界吧! 🎉

Read more

最新最详细的配置Node.js环境教程

配置Node.js环境 * 一、前言 * (一)为什么要配置Node.js? * (二)NPM生态是什么 * (三)Node和NPM的区别 * 二、如何配置Node.js环境 * 第一步、安装环境 * 第二步、安装步骤 * 第三步、验证安装 * 第四步、修改全局模块下的安装路径 * 第五步、更换npm源为淘宝镜像源 * 六、全局安装基于淘宝源的cnpm * 【报错】 * 【尝试】 * 【临时解决方案】 * 三、总结 2024/3/14 一、前言 (一)为什么要配置Node.js? 运行JavaScript文件通常需要要配置Node.js,主要基于几个原因: 1. JavaScript环境:传统的JavaScript是在浏览器环境中运行的,依赖于浏览器提供的API(如DOM操作、网络请求等)。然而,在服务器或本地环境中并没有这些浏览器API。

By Ne0inhk
Flutter 组件 dart_json_mapper_mobx 适配鸿蒙 HarmonyOS 实战:响应式 JSON 映射,构建非侵入式状态绑定与高性能序列化架构

Flutter 组件 dart_json_mapper_mobx 适配鸿蒙 HarmonyOS 实战:响应式 JSON 映射,构建非侵入式状态绑定与高性能序列化架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 dart_json_mapper_mobx 适配鸿蒙 HarmonyOS 实战:响应式 JSON 映射,构建非侵入式状态绑定与高性能序列化架构 前言 在鸿蒙(OpenHarmony)生态迈向全场景分布式联动、涉及复杂业务状态云端同步、大型本地配置反序列化及严苛 UI 刷新性能要求的背景下,如何实现一套既能保障业务模型(Model)的纯净性、又能与响应式状态管理(MobX)深度无缝融合的数据映射架构,已成为决定应用开发敏捷度与运行效能感的关键。在鸿蒙设备这类强调 AOT 极致性能与低堆内存占用的环境下,如果应用依然采用侵入式的 factory ToJson 或冗余的手写解析代码,由于由于业务逻辑与映射逻辑的重度耦合,极易由于由于“代码量激增”或“状态丢失”导致鸿蒙应用在处理高频数据流时发生状态不稳。 我们需要一种能够基于注解(Annotations)自动完成映射、支持

By Ne0inhk
基于Rust实现爬取 GitHub Trending 热门仓库

基于Rust实现爬取 GitHub Trending 热门仓库

基于Rust实现爬取 GitHub Trending 热门仓库 这个实战项目将使用 Rust 实现一个爬虫,目标是爬取 GitHub Trending 页面的热门 Rust 仓库信息(仓库名、描述、星标数、作者等),并将结果输出为 JSON 文件。本次更新基于优化后的代码,重点提升了错误处理容错性和 CSS 选择器稳定性。 技术栈 * HTTP 请求:reqwest( Rust 最流行的 HTTP 客户端,支持异步) * HTML 解析:scraper(基于 selectors 库,支持 CSS 选择器,轻量高效) * JSON 序列化:serde + serde_json( Rust 标准的序列化

By Ne0inhk