编程启蒙|Scratch 转 Python 系列第 15 天:类与对象积木双向对照(AI 角色类封装实战)
一、本篇摘要
Phase C 开启——面向对象编程(OOP)。这是所有专业 Python 工程师必学的核心能力,也是所有 AI Agent 框架的底层设计模式。
好消息是——Scratch 从头到尾就在教 OOP,只是没告诉你名字。Scratch 里的"精灵(Sprite)"就是 Python 里的对象,精灵的位置、大小、造型就是对象的属性,精灵上的自定义积木就是对象的方法。
今天我们把这个熟悉的概念升级成 Python 的 class,然后用它做一个真正的AI 角色封装系统。
二、本节课学习目标
- 理解 **“类"和"对象”**的区别——类是模板,对象是实例,就像 Scratch 里"精灵造型"和"每个精灵克隆体"的关系。
- 掌握
class定义、__init__构造方法、self的作用,会为类添加实例方法。 - 区分类属性(所有对象共享)和实例属性(每个对象独立)。
- 完成一个 AI 角色类(客服/翻译/助教),每种角色有独立属性和行为,为 Day 16 继承打基础。
三、专业名词通俗释义
| 专业名词 | 通俗解释 | Scratch 类比 |
|---|---|---|
类(Class) |
一个模板/蓝图 | Scratch 精灵造型库里的"精灵模板" |
对象(Object) |
类实例化后的具体物件 | 从模板复制出来的每一个精灵 |
| 实例化 | 用类创建对象的过程 | 拖一个精灵到舞台上 |
属性(Attribute) |
对象自己的数据 | 精灵的 x/y 坐标、大小、方向 |
方法(Method) |
对象能做的动作 | 精灵上定义的自定义积木 |
self |
方法里指代"当前对象自己"的关键字 | Scratch 里"这个精灵"的默认视角 |
四、分模块双向对照
模块 1:什么是类和对象——一句话讲透
类是**"狗"这个概念**——四条腿、会叫、会摇尾巴。
对象是**“我家的小黄”**——具体是金毛,3 岁,此时在客厅睡觉。
类是抽象模板,对象是具体存在。你用类创建对象,同一个类可以创建无数个对象。
Scratch 类比:你在造型库里选了一个"猫"造型 → 那是类;你把它拖到舞台上,得到具体位置、大小的猫 → 那是对象。你可以拖多只,每只是独立的对象。

模块 2:定义类——最简单的类

把这个精灵克隆一份(实例化)
# 【Scratch积木】新建自定义积木类别「Dog」
class Dog:
pass # 空类,什么都没有
# 【Scratch积木】把这个精灵克隆一份(实例化)
my_dog = Dog()
your_dog = Dog()
print(my_dog) # <__main__.Dog object at 0x...>
print(my_dog is your_dog) # False,两个独立对象
核心易错说明:类名首字母大写(Dog 而非 dog),这是 Python 官方约定,工程界严格遵守。
模块 3:init 构造方法——对象出生时做什么

# 【Scratch积木】当精灵被克隆时执行:设置初始 x/y/大小
class Dog:
def __init__(self, name, age):
self.name = name # 保存"名字"属性
self.age = age # 保存"年龄"属性
my_dog = Dog("小黄", 3)
your_dog = Dog("旺财", 5)
print(my_dog.name, my_dog.age) # 小黄 3
print(your_dog.name, your_dog.age) # 旺财 5
核心易错说明:
__init__前后各两个下划线,少一个都不认识,Python 里叫魔法方法。self是约定俗成的名字,写this或me也能跑,但不专业——所有 Python 代码都用self。
模块 4:self 到底是啥
self 就是"当前正在被操作的这个对象自己"。类似 Scratch 自定义积木里默认操作"这个精灵"——同样的积木在不同精灵上执行时,操作的是各自的属性。
class Dog:
def __init__(self, name):
self.name = name
my_dog = Dog("小黄")
# my_dog.name = my_dog 这个对象的 name 属性
调用 my_dog.name 时,Python 自动把 my_dog 传给 self——你不用手动传第一个参数。
模块 5:实例方法——让对象"会做事"

# 【Scratch积木】给精灵添加自定义积木「叫一声」「介绍自己」
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} 汪汪汪!")
def introduce(self):
print(f"我叫 {self.name},今年 {self.age} 岁")
my_dog = Dog("小黄", 3)
my_dog.bark() # 小黄 汪汪汪!
my_dog.introduce() # 我叫 小黄,今年 3 岁
核心易错说明:所有实例方法第一个参数必须是 self,忘了 self 会报"多了一个参数"的错误。
模块 6:类属性 vs 实例属性
class Dog:
species = "犬科动物" # 类属性:所有实例共享
def __init__(self, name):
self.name = name # 实例属性:每个实例独立
my_dog = Dog("小黄")
your_dog = Dog("旺财")
print(my_dog.species) # 犬科动物
print(your_dog.species) # 犬科动物(共享)
print(my_dog.name) # 小黄
print(your_dog.name) # 旺财(各自的)
核心易错说明:类属性适合放所有实例共同的常量(如物种、版本号);实例属性适合每个实例独有的数据(如名字、年龄)。
五、综合实战项目:AI 角色类封装系统
项目目标:定义一个 AIRole 类,每个实例是一个不同人设的 AI 角色(客服/翻译/助教)——属性存人设,方法负责回复。为 Day 16 继承和 Day 17 聊天机器人打底。
Scratch 积木流程:
- 新建
AIRole类(相当于新建精灵模板) __init__里保存 4 个属性:name/role/style/history- 定义
greet()chat()show_history()三个方法 - 实例化 3 个不同人设的角色测试
Python 完整可运行源码:
class AIRole:
"""AI 角色类模板"""
# 【Scratch积木】类属性:所有 AI 角色共享的版本号
version = "1.0"
# 【Scratch积木】__init__ 构造:初始化角色属性
def __init__(self, name, role, style):
self.name = name # 角色名字
self.role = role # 职责(客服/翻译/助教)
self.style = style # 说话风格
self.history = [] # 对话历史(每个实例独立)
# 【Scratch积木】定义积木「打招呼」
def greet(self):
print(f"👋 你好,我是 {self.name},一个 {self.style} 的 {self.role}")
# 【Scratch积木】定义积木「聊天」
def chat(self, user_input):
# 简单模拟根据 role 给出不同风格回复
reply_map = {
"客服": f"感谢咨询!关于「{user_input}」,我来为您解答...",
"翻译": f"[Translation] Your text: {user_input}",
"助教": f"这是个好问题!关于「{user_input}」,我们一步步分析...",
}
reply = reply_map.get(self.role, f"我收到了:{user_input}")
self.history.append((user_input, reply))
return reply
# 【Scratch积木】定义积木「查看对话历史」
def show_history(self):
if not self.history:
print("📭 暂无对话")
return
print(f"\n=== {self.name} 的对话记录 ===")
for i, (q, a) in enumerate(self.history, 1):
print(f"{i}. 你:{q}")
print(f" {self.name}:{a}")
# 【Scratch积木】定义积木「清空历史」
def clear_history(self):
self.history.clear()
print(f"🧹 {self.name} 的历史已清空")
# ========== 使用示例 ==========
def main():
# 【Scratch积木】实例化 3 个不同人设的角色
kefu = AIRole("小助手", "客服", "热情耐心")
fanyi = AIRole("Sara", "翻译", "专业严谨")
zhujiao = AIRole("小张老师", "助教", "循循善诱")
# 每个角色独立打招呼
kefu.greet()
fanyi.greet()
zhujiao.greet()
# 每个角色独立聊天,历史互不干扰
print("\n---- 测试对话 ----")
print(kefu.chat("怎么退款"))
print(fanyi.chat("hello world"))
print(zhujiao.chat("Python 循环怎么学"))
# 展示各自历史(证明属性独立)
kefu.show_history()
fanyi.show_history()
zhujiao.show_history()
# 【Scratch积木】读取类属性(所有角色共享)
print(f"\n所有 AI 角色版本:{AIRole.version}")
if __name__ == "__main__":
main()
运行方式:保存为 day15_code.py → python day15_code.py。观察三个角色如何互不干扰地独立工作。
💡 为什么面向对象是革命性的:如果用之前的字典写法,管 3 个角色就要 3 套变量、3 套函数。用类只需要
role1 = AIRole(...)、role2 = AIRole(...)——代码量减半,逻辑清晰十倍。等孩子学到 Day 20 的 AI Agent 系统,就会发现"没有类基本没法写"。
六、高频易错点总结
1. 忘写 self
def bark(): # ❌ 缺 self
print("汪!")
def bark(self): # ✅
print("汪!")
2. __init__ 拼写错
__init__(前后各两个下划线)——写成 _init_ 或 __int__ 会默默不生效,属性没被初始化,后面调用属性直接报错。
3. 类属性和实例属性搞混
class Dog:
tricks = [] # ❌ 可变类属性,所有实例共享!
d1 = Dog()
d1.tricks.append("roll")
d2 = Dog()
print(d2.tricks) # ["roll"] —— 惊喜!
结论:列表、字典类型的属性一律放 __init__ 里做实例属性。
4. 属性名和参数名混用
def __init__(self, name):
name = name # ❌ 只赋值给了局部变量
self.name = name # ✅ 赋值给实例
5. 类名不大写
class dog: 能跑但不专业——工程界规矩:类名大驼峰(AIRole、MyService)。
七、💡 学习提示
为鼓励大家动手练习、吃透编程逻辑,本篇不提供 Scratch 成品源码,请对照截图亲手搭建积木完成复刻!
配套 Python 代码可直接复制运行学习。
八、往期历史笔记
-
编程启蒙|Scratch 转 Python 系列第 3 天:循环重复积木双向对照(AI 批量循环处理,已收录 AI Agent 技术社区)
-
编程启蒙|Scratch 转 Python 系列第 5 天:自定义积木 / 函数双向对照(AI 工具封装、重复指令简化实战)
-
编程启蒙|Scratch 转 Python 系列第 6 天:列表、数组积木双向对照(AI 底层语法 / AI 批量数据处理实战)
-
编程启蒙|Scratch 转 Python 系列第 7 天:猜数字大挑战·升级版实战(AI 出题 + 二分查找最优解 + 完整命令行游戏 已被收录在智能体开发者社区)
-
编程启蒙|Scratch 转 Python 系列第 12 天:记忆翻牌游戏实战(AI 图案主题包 + 存档排行榜 已被收录在2048 AI社区)
-
编程启蒙|Scratch 转 Python 系列第 13 天:异常处理 try/except 积木双向对照(AI 接口调用容错实战)
-
编程启蒙|Scratch 转 Python 系列第 14 天:AI 提示词管理工具实战(增删改查 + 存档导入 + 异常兜底)
十、下一章预告
Scratch 转 Python 系列第 16 天:继承与多态积木双向对照(AI Agent 角色体系实战)
今天做的 AIRole 里,客服、翻译、助教都写在一个 chat 方法的 if 里——代码越加越长。继承能让每种角色独立成一个子类,各写各的,主类只留最通用的部分。
十一、原创声明
本文为「梅雅达编程笔记」原创启蒙教程,禁止私自搬运、二次转载,转发请标注来源。
想要系统学完整套 Scratch 转 Python 课程,欢迎订阅下方专栏持续追更。
更多推荐


所有评论(0)