一、先搞懂两个编程思想:面向过程 vs 面向对象
1. 大白话解释
-
面向过程
只管一步一步按顺序做事,数据是数据、干活的函数是函数,两者是分开的。
像流水线:买菜→洗菜→切菜→炒菜,按步骤走完。
-
面向对象 OOP
先归类建模板 ,再用模板造出一个个具体个体;个体自带数据、自带会做的事,不用管步骤,直接让个体自己干活。
像先定义「学生模板」,再造出张三、李四,每个人自己能报名字、查成绩。
2. 官方案例对照(学生成绩)
① 面向过程写法(数据和函数分家)
# 用字典存学生数据
std1 = {'name': 'Michael', 'score': 98}
std2 = {'name': 'Bob', 'score': 81}
# 单独写一个函数,专门打印成绩
def print_score(std):
print(f"{std['name']}: {std['score']}")
# 调用
print_score(std1)
print_score(std2)
缺点:学生多了很乱,想给学生加「年龄、班级」还要改好多地方,不好维护。
② 面向对象写法(数据 + 功能打包在一起)
# 1. 定义学生 类(模板)
class Student(object):
# 初始化:给每个学生绑定名字、分数
def __init__(self, name, score):
self.name = name # 自己的名字
self.score = score # 自己的分数
# 学生自己的方法:打印自己的成绩
def print_score(self):
print(f"{self.name}: {self.score}")
# 2. 用模板创建 实例(具体的学生)
bart = Student('Bart Simpson', 59)
lisa = Student('Lisa Simpson', 87)
# 3. 让实例自己干活
bart.print_score()
lisa.print_score()
二、核心必背概念
-
类 Class
抽象模板、图纸、分类。
例:
Student是「学生」这个大类,不是某一个具体人。 -
实例 Instance
根据类造出来的具体个体。
例:
bart、lisa是两个真实的学生。 -
属性
对象身上存的数据:名字、分数、年龄。
-
方法
对象自己会做的函数:打印成绩、修改分数。
口诀:先有类(图纸)→ 再造实例(成品)→ 实例有属性、有方法
三、关键语法逐句拆解
class Student(object):
定义一个叫 Student 的类,object 是所有类的祖宗,固定写法记住就行。
def __init__(self, name, score):
-
__init__:构造方法 ,创建实例时自动调用 -
self:必须写,代表自己这个实例本身 -
name, score:创建对象时要传进来的参数self.name = name
self.score = score
把传进来的名字、分数,绑定到当前实例身上,变成自己的属性。
def print_score(self):
print(f"{self.name}: {self.score}")
类里面的函数叫方法 ,第一个参数必须是 self,通过 self.属性 调用自己的数据。
bart = Student('Bart Simpson', 59)
用 Student 类,创建一个实例 bart,传入名字和分数。
四、面向对象三大特征(先记结论,后面细学)
封装、继承、多态
- 封装:把数据和方法打包在类里,藏起内部细节,只用对外方法操作。
- 继承:子类可以直接拿走父类的属性和方法,不用重复写代码。
- 多态:不同子类,调用同一个方法,表现出不同效果。
五、随堂练习题
练习 1:基础仿写(照着改)
要求:
- 定义一个
Cat类 - 属性:名字
name、颜色color - 方法:
miao()打印xx颜色的xx在喵喵叫 - 创建 2 个猫咪实例,调用
miao()方法
可以先自己写,不会我给你标准答案。
#代码
class Cat:
def __init__(self, name,color):
self.name=name
self.color=color
def miao(self):
print(f'{self.color}颜色的{self.name}在喵喵叫')
cat1=Cat('小白','白色') #构造实例 #错误写法❌️:cat1=miao('小白','白色')
cat1.miao()#执行#错误写法:cat1.miao 没有括号不会执行
cat2=Cat(name='黑猫警长',color='黑白相间')
cat2.miao()
知识点
1、创建对象只能用 类名 ()
正确:cat1 = Cat(参数)
错误:cat1 = miao(参数) ❌ 不能用方法造对象
2、调用方法必须带小括号
正确:cat1.miao()
错误:cat1.miao ❌ 只是引用,不执行
3、传参两种都可以
- 按顺序:
Cat('小白','白色') - 关键字:
Cat(name='', color='')不容易搞混顺序
4、self.xxx 就是对象自己的属性
类里面想用名字、颜色,一律 self.name、self.color
练习 2:加功能拓展
在上面 Cat 类基础上,再加一个方法:
-
show_info()打印:名字:xx,颜色:xx创建 3 只猫,分别调用两个方法。
#代码 class Cat: def __init__(self, name,color): self.name=name self.color=color def miao(self): print(f'{self.color}颜色的{self.name}在喵喵叫') def showinfo(self): print('名字:',self.name,'颜色:',self.color) cat1=Cat('小白','白色') #构造实例 #错误写法❌️:cat1=miao('小白','白色') cat1.miao()#执行#错误写法:cat1.miao 没有括号不会执行 cat2=Cat(name='黑猫警长',color='黑白相间') cat2.miao() cat3=Cat(name='小黄',color='黄色') cat3.showinfo()
知识点
帮你记这个打印规则
-
普通打印:字符串 和 变量之间必须加逗号
print('名字:', self.name) -
f-string 懒人写法:引号里用 {变量} 直接嵌
print(f'名字:{self.name}')以后统一用 f-string,不容易写错
练习 3:理解类和实例
判断对错(口答即可)
class是具体的某一个对象 ❌️self可以随便改成别的单词,比如me❌️__init__方法是创建对象时自动执行的✅️
我给你把每一条讲透、帮你记牢:
-
class是具体的某一个对象 ❌✅ 正确理解:
class 是模板 / 图纸,不是具体对象;
cat1、cat2这种才是具体实例对象。 -
self可以随便改成别的单词,比如me❌👉 其实这句严格来说是对的 ,但行业约定必须用 self
-
Python 语法上:可以改成 me、this 都能跑
-
规矩上必须写 self,所有人都默认看 self,改了不规范、别人看不懂。
所以做题判错没问题,按考试记:
固定写 self,不能乱改。
-
__init__方法是创建对象时自动执行的 ✅完全正确
只要写
cat1 = Cat(...)程序就会
自动跑去执行
__init__,不用手动调用。
帮你浓缩三句背诵版:
- class 是模板,实例才是真实对象
- self 是约定,不许随便改名
- *init* 造对象自动触发
=分割线=理解_init_
__init__ 能不能随便写?会不会重复?
一、__init__ 可以写任何内容吗?
可以!完全可以
__init__ 本质就是一个普通函数 ,只是被 Python 设定成:创建实例时自动执行。
里面能写的内容和普通函数一模一样:
- 可以定义属性
self.name = name - 可以写
if判断、循环for - 可以打印东西
print() - 可以计算、赋值、调用其他方法
举个例子:__init__ 里写各种逻辑
class Student:
def __init__(self, name, score):
# 1. 正常绑定属性
self.name = name
self.score = score
# 2. 随便写打印
print("正在创建一个学生对象...")
# 3. 写if判断
if score >= 60:
self.level = "及格"
else:
self.level = "不及格"
调用:
s = Student("小明", 70)
print(s.level)
✅ 完全合法,运行正常。
结论:
__init__ 不是只能写赋值,想写什么逻辑都可以。
二、会不会重复?什么叫 "重复"?
分两种情况给你讲清楚:
情况 1:一个类里写两个 *init* → 会覆盖、算重复、报错逻辑
Python 一个类只能有一个 __init__。
如果你写两个:
class Student:
# 第一个
def __init__(self):
print("第一个构造方法")
# 又写一个
def __init__(self, name):
self.name = name
👉 生效的只有最后一个,前面的直接被覆盖作废。
Python 不支持多个构造方法重载,写多个就是重复覆盖,不建议这么干。
情况 2:每个实例都有自己的 __init__ 执行 → 不会冲突、不会重复
class Student:
def __init__(self, name):
self.name = name
print("执行了一次init")
# 创建第一个实例
s1 = Student("小明")
# 创建第二个实例
s2 = Student("小红")
输出:
执行了一次init
执行了一次init
- 创建 1 个实例 → 自动执行 1 次 *init*
- 每个实例的
__init__都是各自独立跑 - 互相不干扰、数据不打架、不会重复冲突
就像:
图纸(类)只有一张
但可以造 10 个手机(10 个实例)
每造一台,流水线(__init__)就跑一次,互不影响。
三、关键总结(背这 3 句就行)
__init__可以写任意代码:判断、循环、打印、计算都能写,不只能赋值属性。- 一个类里不能写两个
__init__,后面的会覆盖前面的,属于重复无效。 - 创建多个实例时 ,每个实例都会单独跑一遍
__init__,互相独立,不会重复冲突。
=分割线=理解总结
给你改成【完全正确、可以直接背】的理解
你按这个记,完全没问题:
- class 用来定义类 ,类名可以自己随便起名,规范是首字母大写。
- 类里面可以选择性写一个
__init__方法(前后双下划线)。 __init__不用手动调用 ,只要创建实例的一瞬间,Python 会自动调用它。__init__的作用:专门给新创建的实例初始化属性、赋初始值。
括号内的内容:
def __init__(self, 参数1, 参数2, ...):
-
第一位:必须写 self,雷打不动
-
第二位往后:你自己随便定义,想写几个参数就写几个
可以是 name、score、age、height 随便起
关键口诀(背下来)
__init__括号第一个永远是 selfself代表实例自己self.xxx就是给自己这个实例加属性- 除了第一个
self,后面参数随便自己定义