做网站的微信号,全国招聘网最新招聘信息,开发者选项怎么关闭,织梦 做网站 知乎文章目录 一、为什么需要类#xff1f;先看 “字典 函数” 的痛点场景#xff1a;管理 3 个学生的信息#xff08;姓名、年龄、多门成绩#xff09;用 “字典 函数” 处理#xff08;繁琐#xff09;用 “类” 处理#xff08;简洁#xff09; 二、类的基础#xff…文章目录一、为什么需要类先看 “字典 函数” 的痛点场景管理 3 个学生的信息姓名、年龄、多门成绩用 “字典 函数” 处理繁琐用 “类” 处理简洁二、类的基础从定义到实例化1. 定义类用class关键字示例定义Person类基础类2. 创建实例根据类生成具体对象示例创建Person实例3. 访问属性和方法实例的核心操作示例操作Person实例4. 类属性所有实例共享的属性示例定义和使用类属性三、类的进阶继承与方法重写1. 继承的基本用法子类继承父类示例Student类继承Person类2. 多继承可选子类继承多个父类3. 组合类之间的 “包含” 关系示例Student类包含Course类的实例四、综合实操学生管理系统类版完整代码运行结果五、新手必踩的 5 个坑避坑指南坑 1忘记写__init__方法导致实例没有属性坑 2self参数遗漏或位置错误坑 3继承时忘记调用super().__init__坑 4混淆实例属性和类属性坑 5方法调用时传了self参数六、小结与下一篇预告这篇你学到了什么下一篇预告欢迎回到「Python 从入门到实战」系列专栏。上一篇咱们掌握了函数和模块化能把重复逻辑封装成函数通过模块复用代码。但在处理 “相似对象” 时比如多个学生、多个教师函数 字典的组合会显得繁琐比如每个学生要存姓名、年龄、成绩每个教师要存姓名、年龄、工资用字典存储时每次创建对象都要重复定义键调用函数时还要频繁传递字典参数既不直观也容易出错。今天咱们要学 Python 的 “面向对象核心”——类Class。它就像一个 “对象模板”能把 “数据属性” 和 “操作数据的逻辑方法” 封装在一起。比如用Student类定义学生的模板包含 “姓名、年龄、成绩” 这些属性以及 “显示成绩、计算平均分” 这些方法创建具体学生比如小明、小红时直接用模板实例化即可不用重复写字典和函数。学会类你就能更灵活地模拟现实中的对象为后面的复杂项目比如游戏角色、Web 用户系统打基础。一、为什么需要类先看 “字典 函数” 的痛点在学类的语法前先通过 “处理学生信息” 这个场景对比 “字典 函数” 和 “类” 的差异感受类的价值。场景管理 3 个学生的信息姓名、年龄、多门成绩用 “字典 函数” 处理繁琐python运行# 1. 用字典存储每个学生的信息student1{name:小明,age:15,scores:[85,92,76]}student2{name:小红,age:14,scores:[95,88,90]}student3{name:小刚,age:15,scores:[78,80,65]}# 2. 用函数处理学生数据计算平均分、显示信息defcalculate_average(scores):计算平均分returnsum(scores)/len(scores)ifscoreselse0defshow_student_info(student):显示学生信息avgcalculate_average(student[scores])print(f姓名{student[name]}年龄{student[age]}平均分{avg:.1f})# 3. 逐个处理学生每次都要传字典参数show_student_info(student1)show_student_info(student2)show_student_info(student3)这段代码能运行但有两个明显痛点重复定义结构每个学生字典都要写name“age”“scores” 这些键容易漏写或写错函数依赖外部参数show_student_info必须传student字典调用时要确保字典结构正确否则会报KeyError比如漏了scores键。用 “类” 处理简洁用Student类定义学生模板创建实例时直接传参数调用方法时不用传字典python运行# 1. 定义Student类模板classStudent:学生类封装学生的属性和方法def__init__(self,name,age,scores):# 初始化属性姓名、年龄、成绩self.namename self.ageage self.scoresscores# 方法1计算平均分defcalculate_average(self):returnsum(self.scores)/len(self.scores)ifself.scoreselse0# 方法2显示学生信息defshow_info(self):avgself.calculate_average()print(f姓名{self.name}年龄{self.age}平均分{avg:.1f})# 2. 创建学生实例具体对象student1Student(小明,15,[85,92,76])student2Student(小红,14,[95,88,90])student3Student(小刚,15,[78,80,65])# 3. 调用实例方法直接用实例调用不用传参数student1.show_info()student2.show_info()student3.show_info()运行结果和前面完全一致但代码更简洁不用重复定义字典键类的__init__方法已经固定了属性结构调用方法时不用传字典实例student1直接调用show_info()即可因为方法内部能直接访问实例的属性self.name等。这就是类的核心价值封装对象的 “属性” 和 “方法”统一结构减少重复代码降低调用成本。二、类的基础从定义到实例化类是 “对象的模板”实例是 “根据模板创建的具体对象”。比如Student类是模板student1小明是实例。咱们从 “定义类”“创建实例”“访问属性和方法” 这三个核心步骤入手逐步掌握类的基础用法。1. 定义类用class关键字定义类的基本语法如下核心是class关键字、类名、__init__方法初始化属性和自定义方法操作逻辑python运行class类名:类的文档字符串描述类的功能def__init__(self,参数1,参数2,...):初始化实例的属性构造方法# 给实例绑定属性self.属性名 参数self.属性1参数1self.属性2参数2def方法名1(self,可选参数...):自定义方法操作属性的逻辑# 方法体可访问self.属性passdef方法名2(self,可选参数...):另一个方法pass几个关键概念class告诉 Python “这是一个类”类名要遵循 “驼峰命名法”每个单词首字母大写比如Student“UserManager”和函数 / 变量的蛇形命名法区分__init__方法特殊的 “构造方法”创建实例时自动调用用于初始化实例的属性。__init__两边各有两个下划线是 Python 的特殊方法标识不能写错self必须作为__init__和所有方法的第一个参数代表 “当前实例本身”。通过self.属性名可以给实例绑定属性通过self.方法名()可以调用实例的其他方法属性实例的数据比如学生的name“age”通过self.属性名定义方法实例的操作逻辑比如calculate_average“show_info”本质是封装在类里的函数。示例定义Person类基础类先定义一个简单的Person类包含 “姓名、年龄” 两个属性以及 “显示信息” 的方法python运行classPerson:人类的基础类包含姓名和年龄属性以及显示信息的方法def__init__(self,name,age):# 初始化属性self.name绑定姓名self.age绑定年龄self.namename self.ageagedefshow_info(self):显示个人基本信息print(f姓名{self.name}年龄{self.age}岁)# 打印类的文档字符串查看类的功能print(Person.__doc__)# 输出人类的基础类包含姓名和年龄属性以及显示信息的方法2. 创建实例根据类生成具体对象创建实例也叫 “实例化”的语法很简单实例名 类名(参数1, 参数2, ...)参数要和__init__方法除了self之外的参数对应。示例创建Person实例python运行# 创建两个Person实例小明和小红xiaomingPerson(小明,15)xiaohongPerson(小红,14)# 查看实例的类型确认是Person类的实例print(type(xiaoming))# 输出class __main__.Person创建实例时Python 会自动调用__init__方法执行Person(小明, 15)时Python 创建一个空实例自动调用__init__(xiaoming, 小明, 15)self就是刚创建的空实例给实例绑定name小明“age15” 两个属性返回绑定好属性的实例赋值给xiaoming。3. 访问属性和方法实例的核心操作创建实例后通过 “实例名.属性名” 访问属性通过 “实例名.方法名()” 调用方法不用传self参数Python 会自动传递。示例操作Person实例python运行# 1. 访问实例属性print(xiaoming.name)# 输出小明访问name属性print(xiaohong.age)# 输出14访问age属性# 2. 修改实例属性xiaoming.age16# 修改小明的年龄为16print(f小明修改后的年龄{xiaoming.age}岁)# 输出小明修改后的年龄16岁# 3. 调用实例方法xiaoming.show_info()# 输出姓名小明年龄16岁调用show_info方法xiaohong.show_info()# 输出姓名小红年龄14岁这里要注意调用方法时不用传self参数Python 会自动把实例本身作为self传入方法所以方法内部能通过self访问实例的属性和其他方法。4. 类属性所有实例共享的属性除了 “实例属性”每个实例独有的属性比如小明的age和小红的age还有 “类属性”—— 所有实例共享的属性比如Person类的 “物种” 属性所有Person实例的物种都是 “人类”。类属性直接定义在类的内部、__init__方法之外通过 “类名.属性名” 或 “实例名.属性名” 访问。示例定义和使用类属性python运行classPerson:# 类属性所有Person实例共享物种都是“人类”species人类def__init__(self,name,age):# 实例属性每个实例独有的属性self.namename self.ageagedefshow_info(self):# 方法中访问类属性self.species 或 Person.speciesprint(f物种{self.species}姓名{self.name}年龄{self.age}岁)# 创建实例xiaomingPerson(小明,15)xiaohongPerson(小红,14)# 访问类属性print(Person.species)# 输出人类通过类名访问print(xiaoming.species)# 输出人类通过实例名访问# 调用方法方法内部访问类属性xiaoming.show_info()# 输出物种人类姓名小明年龄15岁# 修改类属性所有实例都会受影响Person.species智人print(xiaohong.species)# 输出智人小红的species也变了关键区别实例属性每个实例独有修改一个实例的属性不影响其他实例类属性所有实例共享修改类属性会影响所有实例。三、类的进阶继承与方法重写当多个类有重复属性和方法时比如Student和Teacher都有 “姓名、年龄”都要 “显示信息”可以用继承减少重复代码。继承让 “子类” 自动拥有 “父类” 的属性和方法子类只需编写自己特有的属性和方法即可。1. 继承的基本用法子类继承父类继承的语法是class 子类名(父类名):子类会自动继承父类的所有属性和方法。比如让Student类继承Person类Student是子类Person是父类也叫超类。示例Student类继承Person类python运行# 父类Person已定义包含name、age属性和show_info方法classPerson:species人类def__init__(self,name,age):self.namename self.ageagedefshow_info(self):print(f姓名{self.name}年龄{self.age}岁)# 子类Student 继承 PersonclassStudent(Person):学生类继承Person类新增成绩属性和计算平均分的方法def__init__(self,name,age,scores):# 调用父类的__init__方法初始化name和age属性避免重复代码super().__init__(name,age)# 子类特有的属性成绩列表self.scoresscores# 子类特有的方法计算平均分defcalculate_average(self):returnsum(self.scores)/len(self.scores)ifself.scoreselse0# 子类重写父类的show_info方法扩展功能defshow_info(self):# 先调用父类的show_info方法super().show_info()# 再添加子类特有的信息平均分avgself.calculate_average()print(f成绩{self.scores}平均分{avg:.1f})# 创建Student实例xiaomingStudent(小明,15,[85,92,76])# 调用子类的方法继承重写新增xiaoming.show_info()# 输出父类的信息子类的成绩信息print(f小明的平均分{xiaoming.calculate_average():.1f})# 调用子类新增方法运行结果plaintext姓名小明年龄15岁 成绩[85, 92, 76]平均分84.3 小明的平均分84.3几个关键知识点super()函数在子类的__init__方法中调用super().__init__(name, age)会自动调用父类的__init__方法初始化父类的属性避免重复写self.name name“self.age age”方法重写子类可以定义和父类同名的方法比如show_info覆盖父类的方法。在重写时可通过super().方法名()调用父类的方法再扩展子类特有的功能子类特有属性 / 方法子类可以添加父类没有的属性比如scores和方法比如calculate_average实现功能扩展。2. 多继承可选子类继承多个父类Python 支持多继承一个子类继承多个父类语法是class 子类名(父类1, 父类2):。但多继承容易导致 “菱形问题”多个父类有同名方法时的优先级问题新手建议优先用 “单继承 组合”这里简单示例python运行# 父类1Person姓名、年龄classPerson:def__init__(self,name,age):self.namename self.ageage# 父类2HasScore成绩相关方法classHasScore:defcalculate_average(self,scores):returnsum(scores)/len(scores)ifscoreselse0# 子类Student 继承 Person 和 HasScoreclassStudent(Person,HasScore):def__init__(self,name,age,scores):super().__init__(name,age)self.scoresscoresdefshow_info(self):avgself.calculate_average(self.scores)# 调用HasScore的方法print(f姓名{self.name}年龄{self.age}平均分{avg:.1f})# 创建实例xiaomingStudent(小明,15,[85,92,76])xiaoming.show_info()# 输出姓名小明年龄15平均分84.33. 组合类之间的 “包含” 关系除了继承“是” 的关系比如Student是Person类之间还有 “包含” 关系比如Student包含Course学生有课程这时候用组合更合适 —— 把一个类的实例作为另一个类的属性。示例Student类包含Course类的实例python运行# 定义Course类课程classCourse:def__init__(self,name,score):self.namename# 课程名self.scorescore# 课程成绩defshow_course(self):returnf{self.name}{self.score}分# 定义Student类包含多个Course实例classStudent:def__init__(self,name,age):self.namename self.ageage self.courses[]# 存储Course实例的列表组合关系# 添加课程defadd_course(self,course):self.courses.append(course)# 显示学生和课程信息defshow_info(self):print(f姓名{self.name}年龄{self.age}岁)print(课程成绩)total_score0forcourseinself.courses:print(f -{course.show_course()})total_scorecourse.score avgtotal_score/len(self.courses)ifself.courseselse0print(f平均分{avg:.1f})# 创建课程实例mathCourse(数学,85)englishCourse(英语,92)# 创建学生实例添加课程xiaomingStudent(小明,15)xiaoming.add_course(math)xiaoming.add_course(english)# 显示信息xiaoming.show_info()运行结果plaintext姓名小明年龄15岁 课程成绩 - 数学85分 - 英语92分 平均分88.5组合比继承更灵活学生可以添加任意多的课程课程的修改比如新增 “课程时长” 属性不会影响学生类符合 “低耦合” 的设计思想。四、综合实操学生管理系统类版咱们用类重构 “学生管理系统”实现以下功能用Course类存储课程信息名称、成绩用Student类存储学生信息姓名、年龄、课程列表包含添加课程、计算平均分、显示信息的方法用StudentManager类管理多个学生实例包含添加学生、显示所有学生、计算班级平均分的方法。完整代码python运行# 1. 课程类存储课程名称和成绩classCourse:def__init__(self,name,score):self.namename self.scorescoredefget_info(self):返回课程的字符串信息returnf{self.name}({self.score}分)# 2. 学生类存储学生信息包含课程列表classStudent:def__init__(self,name,age):self.namename self.ageage self.courses[]# 组合存储Course实例defadd_course(self,course):添加课程接收Course实例ifisinstance(course,Course):# 确保传入的是Course实例self.courses.append(course)print(f✅ 给{self.name}添加课程{course.get_info()})else:print(f❌ 无效课程{course}必须是Course实例)defcalculate_average(self):计算所有课程的平均分ifnotself.courses:return0.0totalsum(course.scoreforcourseinself.courses)returnround(total/len(self.courses),1)defshow_detail(self):显示学生的详细信息print(f\n【学生信息】)print(f姓名{self.name}年龄{self.age}岁)print(f课程数量{len(self.courses)}门)ifself.courses:print(课程列表)forcourseinself.courses:print(f -{course.get_info()})print(f平均分{self.calculate_average()})# 3. 学生管理类管理多个Student实例classStudentManager:def__init__(self):self.students[]# 存储Student实例defadd_student(self,student):添加学生接收Student实例ifisinstance(student,Student):self.students.append(student)print(f\n✅ 添加学生成功{student.name})else:print(f\n❌ 无效学生{student}必须是Student实例)defshow_all_students(self):显示所有学生的信息print(f\n 所有学生信息共{len(self.students)}人)ifnotself.students:print(❌ 暂无学生信息)returnfori,studentinenumerate(self.students,start1):print(f\n{i}. ,end)student.show_detail()defcalculate_class_average(self):计算班级所有学生的平均分总平均分ifnotself.students:return0.0total_avg0.0valid_students0forstudentinself.students:avgstudent.calculate_average()ifavg0:# 排除没有课程的学生total_avgavg valid_students1returnround(total_avg/valid_students,1)ifvalid_studentselse0.0# 4. 主程序使用上述类defmain():print( 学生管理系统类版 )# 创建学生管理器managerStudentManager()# 1. 添加学生1小明xiaomingStudent(小明,15)# 给小明添加课程xiaoming.add_course(Course(数学,85))xiaoming.add_course(Course(英语,92))xiaoming.add_course(Course(语文,76))# 添加到管理器manager.add_student(xiaoming)# 2. 添加学生2小红xiaohongStudent(小红,14)xiaohong.add_course(Course(数学,95))xiaohong.add_course(Course(英语,88))manager.add_student(xiaohong)# 3. 显示所有学生manager.show_all_students()# 4. 计算班级平均分class_avgmanager.calculate_class_average()print(f\n 班级总平均分{class_avg})# 运行主程序if__name____main__:main()运行结果plaintext 学生管理系统类版 ✅ 给小明添加课程数学(85分) ✅ 给小明添加课程英语(92分) ✅ 给小明添加课程语文(76分) ✅ 添加学生成功小明 ✅ 给小红添加课程数学(95分) ✅ 给小红添加课程英语(88分) ✅ 添加学生成功小红 所有学生信息共2人 1. 【学生信息】 姓名小明年龄15岁 课程数量3门 课程列表 - 数学(85分) - 英语(92分) - 语文(76分) 平均分84.3 2. 【学生信息】 姓名小红年龄14岁 课程数量2门 课程列表 - 数学(95分) - 英语(88分) 平均分91.5 班级总平均分87.9 这个系统完全基于类实现每个类职责明确Course管课程Student管学生StudentManager管学生集合后期要添加功能比如删除学生、修改课程成绩只需在对应类中添加方法不用修改其他类扩展性极强。五、新手必踩的 5 个坑避坑指南类的概念和用法比函数复杂新手容易在 “self的使用”“继承逻辑”“属性访问” 等方面踩坑咱们总结 5 个高频坑点坑 1忘记写__init__方法导致实例没有属性python运行# 错误示例忘记__init__实例没有name属性classStudent:# 没有__init__方法没有绑定name属性defshow_info(self):print(f姓名{self.name})# 创建实例时无法传name参数xiaomingStudent(小明)# 报错TypeError: Student() takes no arguments解决必须定义__init__方法在其中绑定实例属性python运行classStudent:def__init__(self,name):self.namename# 绑定name属性defshow_info(self):print(f姓名{self.name})xiaomingStudent(小明)xiaoming.show_info()# 正确输出姓名小明坑 2self参数遗漏或位置错误python运行# 错误示例1方法中遗漏self参数classStudent:def__init__(self,name):self.namenamedefshow_info():# 遗漏selfprint(f姓名{self.name})xiaomingStudent(小明)xiaoming.show_info()# 报错TypeError: show_info() takes 0 positional arguments but 1 was given# 错误示例2self不是第一个参数classStudent:def__init__(name,self):# self位置错误self.namename# 创建实例时报错TypeError: __init__() got multiple values for argument self规则__init__和所有实例方法的第一个参数必须是self不能遗漏或换位置。坑 3继承时忘记调用super().__init__python运行# 错误示例子类继承父类但没调用父类的__init__导致父类属性未初始化classPerson:def__init__(self,name):self.namenameclassStudent(Person):def__init__(self,name,age):# 忘记调用super().__init__(name)父类的name属性未绑定self.ageage xiaomingStudent(小明,15)print(xiaoming.name)# 报错AttributeError: Student object has no attribute name解决子类__init__中必须调用super().__init__(父类参数)初始化父类属性python运行classStudent(Person):def__init__(self,name,age):super().__init__(name)# 调用父类__init__绑定nameself.ageage xiaomingStudent(小明,15)print(xiaoming.name)# 正确输出小明坑 4混淆实例属性和类属性python运行# 错误示例修改实例的类属性误以为会影响所有实例classPerson:species人类# 类属性xiaomingPerson()xiaoming.species外星人# 实际是给实例添加了一个同名的实例属性xiaohongPerson()print(xiaoming.species)# 输出外星人实例属性print(xiaohong.species)# 输出人类类属性未被修改原因给实例赋值 “实例名.类属性名” 时不会修改类属性而是给实例添加一个同名的实例属性。修改类属性必须用 “类名.类属性名”python运行Person.species外星人# 修改类属性print(xiaohong.species)# 输出外星人所有实例的类属性都变了坑 5方法调用时传了self参数python运行# 错误示例调用方法时手动传self参数classStudent:def__init__(self,name):self.namenamedefshow_info(self):print(f姓名{self.name})xiaomingStudent(小明)xiaoming.show_info(xiaoming)# 错误手动传了self参数规则调用实例方法时Python 会自动把实例作为self传入不用手动传self正确写法是xiaoming.show_info()。六、小结与下一篇预告这篇你学到了什么类的基础用class定义类__init__方法初始化属性self代表实例本身创建实例并访问属性 / 方法属性类型实例属性每个实例独有和类属性所有实例共享的区别与用法继承子类继承父类用super()调用父类方法重写父类方法扩展功能组合类之间的 “包含” 关系把一个类的实例作为另一个类的属性灵活关联对象实战应用用多个类协作实现学生管理系统每个类职责明确代码可扩展避坑要点self的使用、继承时super()的调用、实例属性与类属性的区别。下一篇预告今天的类让我们能封装对象的属性和方法但当需要处理 “大量实例” 或 “复杂数据” 时比如读取文件中的学生信息、将数据保存到 Excel还需要结合 “文件操作” 和 “第三方库”。下一篇咱们会学 Python 的 “文件操作”包括读取文本文件、写入文件、处理 CSV 数据让程序能持久化存储数据关闭程序后数据不丢失为后面的实战项目打下数据存储基础。如果这篇内容帮你掌握了类欢迎在评论区分享你的 “类设计”比如设计一个Book类或GameRole类咱们一起交流进步