day-027-面向对象-下

📅 2026/7/13 1:22:03 ✍️ 编辑团队 👁️ 阅读次数
day-027-面向对象-下
Day 27面向对象下——特殊方法与类方法OOP 最后一篇。学会 Python 的魔法方法让你的类像内置类型一样好用了解类方法和静态方法的区别。最后做一个完整的小项目。一、特殊方法魔术方法——让你的类更像 Python以__开头结尾的方法称为特殊方法也叫魔术方法。定义它们能让你的类支持len()、[]、、for...in等内置操作。__len__和__getitem__——支持 len() 和 []classPlaylist:歌单类def__init__(self,name):self.namename self.songs[]defadd_song(self,song):self.songs.append(song)def__len__(self):让 len() 可用returnlen(self.songs)def__getitem__(self,index):让 [] 索引可用returnself.songs[index]def__str__(self):returnf《{self.name}》共{len(self)}首歌# 使用plPlaylist(我的最爱)pl.add_song(晴天)pl.add_song(夜曲)pl.add_song(稻香)print(len(pl))# 3 因为实现了 __len__print(pl[0])# 晴天 因为实现了 __getitem__print(pl[1:])# [夜曲, 稻香] 切片也行forsonginpl:# 实现了 __getitem__就能 for 循环print(song)__eq__、__lt__等——支持比较运算classStudent:def__init__(self,name,score):self.namename self.scorescoredef__eq__(self,other): 操作returnself.scoreother.scoredef__lt__(self,other): 操作实现 __lt__ 后 sorted() 也能用returnself.scoreother.scoredef__repr__(self):returnfStudent({self.name},{self.score})s1Student(小明,85)s2Student(小红,92)s3Student(小刚,78)print(s1s2)# False (比较成绩)print(s1s2)# Truestudents[s1,s2,s3]students.sort()# 按成绩排序因为实现了 __lt__print(students)# [Student(小刚, 78), Student(小明, 85), Student(小红, 92)]__add__、__mul__等——支持运算符classVector:二维向量def__init__(self,x,y):self.xx self.yydef__add__(self,other):支持 运算returnVector(self.xother.x,self.yother.y)def__mul__(self,scalar):支持 * 标量returnVector(self.x*scalar,self.y*scalar)def__repr__(self):returnfVector({self.x},{self.y})v1Vector(1,2)v2Vector(3,4)print(v1v2)# Vector(4, 6)print(v1*3)# Vector(3, 6)二、类方法 classmethod——操作类本身classStudent:school海淀小学def__init__(self,name,score):self.namename self.scorescore# 实例方法第一个参数是 self实例definfo(self):returnf{self.name}({self.school})# 类方法第一个参数是 cls类本身classmethoddefchange_school(cls,new_school):cls.schoolnew_school# 类方法的典型用法替代构造器classmethoddeffrom_string(cls,string):从字符串创建 Student如 小明,85 name,scorestring.split(,)returncls(name.strip(),int(score))# 使用类方法改变类属性Student.change_school(朝阳小学)print(Student.school)# 朝阳小学# 使用类方法创建实例工厂方法sStudent.from_string(小红, 92)print(s.info())# 小红 (朝阳小学)三、静态方法 staticmethod——不属于实例也不属于类classMathUtils:staticmethoddefis_even(n):returnn%20staticmethoddefclamp(value,min_val,max_val):把 value 限制在 [min_val, max_val] 之间returnmax(min_val,min(value,max_val))# 静态方法不需要 self 或 cls直接通过类名调用print(MathUtils.is_even(10))# Trueprint(MathUtils.clamp(15,0,10))# 10三种方法对比方法类型装饰器第一个参数调用方式实例方法无selfobj.method()类方法classmethodclsClass.method()或obj.method()静态方法staticmethod无Class.method()四、实战——学生管理系统面向对象版classStudent:学生类def__init__(self,name,age,score):self.namename self.ageage self.scorescorepropertydefgrade(self):ifself.score90:returnAelifself.score80:returnBelifself.score60:returnCreturnDdef__str__(self):returnf{self.name},{self.age}岁,{self.score}分 ({self.grade})def__repr__(self):returnfStudent({self.name},{self.age},{self.score})classStudentManager:管理学生集合def__init__(self):self.students[]defadd(self,name,age,score):sStudent(name,int(age),int(score))self.students.append(s)returnsdefremove(self,name):self.students[sforsinself.studentsifs.name!name]deffind(self,name):forsinself.students:ifs.namename:returnsreturnNonedef__len__(self):returnlen(self.students)def__iter__(self):让 for s in manager 可用returniter(self.students)deftop_students(self,n3):前 n 名returnsorted(self.students,keylambdas:s.score,reverseTrue)[:n]propertydefaverage(self):ifnotself.students:return0returnsum(s.scoreforsinself.students)/len(self)classmethoddeffrom_csv(cls,filepath):从 CSV 文件创建管理器importcsv managercls()withopen(filepath,r,encodingutf-8)asf:readercsv.DictReader(f)forrowinreader:manager.add(row[姓名],row[年龄],row[成绩])returnmanager# 使用mgrStudentManager()mgr.add(小明,18,85)mgr.add(小红,19,92)mgr.add(小刚,18,78)mgr.add(小丽,20,95)print(f共{len(mgr)}名学生平均分{mgr.average:.1f})print(前3名)forsinmgr.top_students():print(f{s})五、今日学习总结学习内容掌握情况一句话要点__len__/__getitem__✅ 重点让对象支持 len() 和 []__eq__/__lt__✅ 理解比较与排序__add__/__mul__✅ 了解运算符重载classmethod✅ 重点第一个参数是 cls操作类本身staticmethod✅ 理解不需要 self/cls就是个普通函数今日踩坑记录__lt__和__gt__只需实现一个__lt__小于就足够 sorted() 用了。Python 会自动推导__gt__大于。特殊方法要返回新对象还是修改自身__add__应该返回新对象不修改自身__iadd__才修改自身。类方法用错了场景如果不需要用到类属性或创建实例普通函数就够了别硬塞进类里。六、明天学什么OOP 三连结束。明天开始综合练习——把前27天学的全部东西用起来做一个完整的命令行项目。特殊方法让你的类融入 Python 生态类方法让类本身也能做事情。OOP 的工具箱到此齐了。第27天打卡完成。明天见本系列是个人学习笔记如有错误欢迎在评论区指正交流。