(Python)类和类的方法进阶(基础教程介绍)(Python基础教程)
源代码:
class Courses:def __init__(self,name,credit):self.name=nameself.credit=creditself.students=[]def enroll(self,student):self.students.append(student)student.credit+=self.creditreturn f"{student.name}已选课《{self.name}》"class Students:def __init__(self,name,age,sex,credit):self.name = nameself.age = ageself.sex = sexself.credit = creditdef take_course(self,course):return course.enroll(self)math=Courses("高等数学",4)
student=Students("小明",20,"男",0)
result=student.take_course(math)
print(result)
代码解析:
超详细分步解析:校园管理系统
🎯 系统核心目标
学生可以选修课程
课程记录选课学生名单
选课后自动增加学生学分
学生和课程相互关联
🧩 第一步:理解课程类 (Course)
class Course:# 构造方法:创建课程时调用def __init__(self, name, credit):self.name = name # 课程名称(如"高等数学")self.credit = credit # 课程学分(如4分)self.students = [] # 存储选课学生的空列表# 学生选课方法def enroll(self, student):# 1. 把学生添加到课程的学生名单self.students.append(student)# 2. 给学生增加学分student.credit += self.credit# 3. 返回选课成功消息return f"{student.name}已选课《{self.name}》"
类比解释:
想象课程是一个班级:
name
= 班级名称(如"高三(1)班")credit
= 班级能获得的学分students
= 班级花名册(记录所有学生)enroll()
= 学生报到登记的过程
当学生报到时:
在花名册上登记学生姓名 📝
给学生发放学分 💰
告诉学生报到成功 ✅
👨🎓 第二步:理解学生类 (Students)
class Students:# 构造方法:创建学生时调用def __init__(self, name, age, sex, credit):self.name = name # 学生姓名self.age = age # 学生年龄self.sex = sex # 学生性别self.credit = credit # 学生当前学分# 学生选课方法def take_course(self, course):# 调用课程的选课方法,把自己(self)作为参数return course.enroll(self)
类比解释:
想象学生是一个人:
name
= 姓名age
= 年龄sex
= 性别credit
= 钱包里的学分币
take_course()
方法就像学生去选课:
学生走到课程办公室门口 🚶
对课程说:"我要选这门课!"
课程执行
enroll()
登记流程
🔄 第三步:理解整个交互过程
创建课程
math = Course("高等数学", 4)
创建"高等数学"课程
设置学分4分
初始化空学生名单
此时课程状态:
创建学生
student = Students("小明", 20, "男", 0)
创建小明同学
年龄20岁,性别男
初始学分0
此时学生状态:
学生选课
result = student.take_course(math)
print(result) # 输出:小明已选课《高等数学》
发生了什么:
小明调用
take_course(math)
课程执行
enroll(小明)
系统变化:
课程的学生名单:
["小明"]
小明的学分:从0 → 4
结果验证
print(f"小明学分:{student.credit}") # 输出:小明学分:4
print(f"选课学生:{[s.name for s in math.students]}") # 输出:选课学生:['小明']
🧠 重点概念图解
1. 对象关系图
2. 方法调用流程
3. 状态变化对比
操作 | 课程状态 | 学生状态 |
---|---|---|
选课前 | 学生名单:空 学分:4 | 学分:0 |
选课后 | 学生名单:[小明] 学分:4 | 学分:4 |
❓ 常见疑问解答
Q1:为什么学生名单里存储的是对象而不是名字?
A:存储对象(student
)而不是字符串("小明"
),因为:
可以直接访问学生的所有信息(年龄、学分等)
可以调用学生的方法
修改学生信息时自动更新
Q2:student.credit += self.credit
怎么理解?
A:这行代码的意思是:
self.credit
→ 课程的学分(4)student.credit
→ 小明当前的学分(0)相当于:小明的学分 = 0 + 4 → 4
Q3:course.enroll(self)
中的 self
是什么?
A:在学生的 take_course
方法中:
self
代表当前学生对象(小明)所以
course.enroll(self)
就是把小明自己传给课程的选课方法
Q4:[s.name for s in math.students]
是什么语法?
A:这是列表推导式,相当于:
names = []
for s in math.students:names.append(s.name)
print(names)
简写形式,目的是获取所有选课学生的名字列表
🚀 真实场景扩展
假设学校有三门课程和三个学生:
# 创建课程
math = Course("高等数学", 4)
english = Course("大学英语", 3)
programming = Course("Python编程", 5)# 创建学生
alice = Students("Alice", 20, "女", 0)
bob = Students("Bob", 21, "男", 0)
charlie = Students("Charlie", 19, "男", 0)# 学生选课
alice.take_course(math) # Alice选数学
alice.take_course(english) # Alice选英语
bob.take_course(programming) # Bob选编程
charlie.take_course(math) # Charlie选数学# 查看结果
print(f"Alice学分: {alice.credit}") # 4+3=7
print(f"数学课学生: {[s.name for s in math.students]}") # ['Alice', 'Charlie']
print(f"编程课学生: {[s.name for s in programming.students]}") # ['Bob']
这样我们就实现了一个简单的选课系统!通过这个例子,你可以看到:
学生和课程如何交互
对象之间如何建立关联
属性如何动态变化
多说一句(重点理解):
问题1:为什么没有继承就能调用?
在面向对象编程中,继承不是对象交互的唯一方式。对象之间可以通过多种方式交互:
组合(Composition):一个对象包含另一个对象
关联(Association):对象之间相互引用
依赖(Dependency):一个对象使用另一个对象
在你的代码中,学生和课程的关系是关联关系:
class Students:def take_course(self, course): # 学生关联课程return course.enroll(self) # 调用课程的方法class Course:def enroll(self, student): # 课程关联学生student.credit += self.credit # 修改学生属性
为什么不需要继承?
学生不是课程:学生和课程是不同实体
课程不是学生:它们没有"是"关系(is-a)
需要各自独立存在:学生可以没有课程,课程可以没有学生
继承用于"是"关系(如教师是学校成员),而这里是"有"关系(学生有课程)
问题2:命名问题解析
# 类定义:大驼峰命名
class Students: # 类名:Students(复数形式)...# 创建实例:小写命名
student = Students("小明", 20, "男", 0) # 变量名:student(单数)
命名规则:
类型 | 规范 | 你的代码 | 说明 |
---|---|---|---|
类名 | 大驼峰(首字母大写) | Students | 表示学生类 |
实例名 | 小写蛇形 | student | 具体的学生对象 |
方法参数 | 小写蛇形 | course | 方法内的局部变量 |
为什么看起来"不对应"?
类 vs 实例:
Students
是类(模板)student
是实例(具体对象)
就像:
"人类"(类) vs "张三"(实例)
"汽车"(类) vs "我的奔驰车"(实例)
方法中的
self
和student
:
class Course:def enroll(self, student): # 这里的self和student都是参数名# self 代表当前课程对象# student 代表传入的学生对象
注:该代码是本人自己所写,可能不够好,不够简便,欢迎大家指出我的不足之处。如果遇见看不懂的地方,可以在评论区打出来,进行讨论,或者联系我。上述内容全是我自己理解的,如果你有别的想法,或者认为我的理解不对,欢迎指出!!!如果可以,可以点一个免费的赞支持一下吗?谢谢各位彦祖亦菲!!!!!