2026/3/11 9:50:01
网站建设
项目流程
汇鑫科技网站建设,wordpress邮件设置,建设银行长沙招聘网站,高校网络网站建设意义及措施Day 16#xff1a;【99天精通Python】面向对象编程(OOP)下篇 - 魔术方法与类属性
前言
欢迎来到第16天#xff01;
在之前的两天里#xff0c;我们构建了 OOP 的大厦框架。今天#xff0c;我们要进行内部装修#xff0c;学习一些 Python 特有的黑魔法。
你是否…Day 16【99天精通Python】面向对象编程(OOP)下篇 - 魔术方法与类属性前言欢迎来到第16天在之前的两天里我们构建了 OOP 的大厦框架。今天我们要进行内部装修学习一些 Python 特有的黑魔法。你是否好奇过为什么print(obj)打印出来的是一串看不懂的地址而别人的对象打印出来是清晰的信息为什么 Python 的号既能算数字加法又能拼接字符串甚至还能合并列表所有的属性都必须绑定在self上吗有没有属于类本身的属性本节内容类属性 vs 实例属性实例方法、类方法、静态方法魔术方法 (Magic Methods) 详解运算符重载 (__add__,__eq__等)实战练习一、类属性 vs 实例属性1.1 概念区别实例属性定义在__init__中使用self.xxx。每个对象独有一份互不干扰。类属性定义在类内部方法之外。所有对象共享同一份。1.2 使用场景classTool:# 类属性所有工具共享的计数器count0def__init__(self,name):# 实例属性每个工具的名字不同self.namename# 每创建一个对象类属性 count 加 1Tool.count1t1Tool(锤子)t2Tool(扳手)print(f工具1:{t1.name})# 锤子print(f工具2:{t2.name})# 扳手print(f当前工具总数:{Tool.count})# 2注意访问类属性建议直接用类名.属性名(如Tool.count)。虽然t1.count也能访问但容易引起混淆。二、三种方法各司其职Python 的类中可以定义三种方法它们通过装饰器来区分。2.1 实例方法 (Instance Method)默认的方法。第一个参数是self(指向对象)。最常用用于操作实例属性。2.2 类方法 (Class Method)使用classmethod装饰。第一个参数是cls(指向类本身而不是对象)。常用于工厂模式(不通过__init__创建对象) 或操作类属性。2.3 静态方法 (Static Method)使用staticmethod装饰。没有self和cls参数。它就像是一个普通函数只是单纯地寄生在类里面通常作为辅助工具。2.4 代码对比classDateUtil:def__init__(self,year,month,day):self.yearyear self.monthmonth self.dayday# 1. 实例方法打印日期defshow(self):print(f{self.year}-{self.month}-{self.day})# 2. 类方法通过字符串创建对象 (工厂模式)classmethoddeffrom_string(cls,date_str):# date_str 格式 2026-01-01y,m,dmap(int,date_str.split(-))returncls(y,m,d)# 相当于 DateUtil(y, m, d)# 3. 静态方法验证日期是否有效 (不需要访问实例或类属性)staticmethoddefis_valid(date_str):return-indate_str# 使用# 静态方法检查ifDateUtil.is_valid(2026-05-20):# 类方法创建对象dDateUtil.from_string(2026-05-20)# 实例方法显示d.show()# 2026-5-20三、魔术方法 (Magic Methods)在 Python 中以双下划线开头和结尾的方法被称为魔术方法也叫 Dunder Methods。它们会在特定时机被自动调用。__init__就是最常见的魔术方法。3.1 __str__ 与 __repr__让对象说人话当你print(obj)时默认打印的是内存地址。实现__str__可以自定义打印内容。classPerson:def__init__(self,name,age):self.namename self.ageage# 面向用户print() 时调用def__str__(self):returnfPerson(name{self.name}, age{self.age})# 面向开发者命令行交互时调用 (通常用来排查问题)def__repr__(self):returnfPerson{self.name}pPerson(Alice,25)print(p)# Person(nameAlice, age25)3.2 运算符重载让对象支持 - * /为什么 Python 的字符串和列表可以相加因为它们实现了__add__方法。我们也可以让自定义对象支持运算符。示例二维向量相加classVector:def__init__(self,x,y):self.xx self.yydef__str__(self):returnfVector({self.x},{self.y})# 实现 号运算def__add__(self,other):# 返回一个新的 Vector 对象returnVector(self.xother.x,self.yother.y)# 实现 号比较def__eq__(self,other):returnself.xother.xandself.yother.y v1Vector(2,4)v2Vector(3,1)v3v1v2# 自动调用 v1.__add__(v2)print(v3)# Vector(5, 5)print(v1v2)# Falseprint(v1Vector(2,4))# True3.3 其他常用魔术方法__len__(self): 响应len(obj)。__call__(self): 让对象能像函数一样被调用obj()。__getitem__(self, key): 让对象支持索引访问obj[key]。四、实战练习练习1购物车 (支持 len 和打印)定义Cart类内部用列表存储商品。add(item): 添加商品。实现__len__: 返回商品数量。实现__str__: 打印所有商品名称。classCart:def__init__(self):self.items[]defadd(self,item):self.items.append(item)def__len__(self):returnlen(self.items)def__str__(self):returnf购物车包含:{, .join(self.items)}my_cartCart()my_cart.add(苹果)my_cart.add(牛奶)print(len(my_cart))# 2print(my_cart)# 购物车包含: 苹果, 牛奶练习2分数类 (Fraction)实现一个简单的分数类支持分数的相加。例如1/2 1/4 3/4。classFraction:def__init__(self,top,bottom):self.toptop# 分子self.bottombottom# 分母def__str__(self):returnf{self.top}/{self.bottom}def__add__(self,other):# 通分公式: a/b c/d (ad bc) / bdnew_topself.top*other.bottomother.top*self.bottom new_bottomself.bottom*other.bottomreturnFraction(new_top,new_bottom)f1Fraction(1,2)f2Fraction(1,4)print(f1f2)# 6/8 (暂时不涉及约分逻辑)五、OOP 总结与回顾到今天为止OOP 的核心内容就讲完了。让我们回顾一下OOP 体系类与对象class 定义obj 实例self 关键字三大特性保护数据复用代码灵活调用高级特性类属性 vs 实例属性classmethod...str,add...六、常见问题Q1__init__和__new__有什么区别__new__是真正创建对象实例的方法构造器。__init__是对象创建好后初始化属性的方法初始化器。99% 的情况我们只需要写__init__除非你在做单例模式或继承不可变类型。Q2什么时候用staticmethod当你写了一个方法发现它既不需要访问self(实例属性)也不需要访问cls(类属性)但逻辑上又跟这个类有关联时就把它定义为静态方法。七、小结OOP 进阶属性类型方法类型魔术方法实例属性 (self.x) - 独享类属性 (Class.x) - 共享实例方法 (self)类方法 classmethod (cls)静态方法 staticmethodstr(打印)add(运算)len(长度)关键要点想要所有对象共享数据用类属性。想要自定义print()的显示效果写__str__。想要让对象支持运算写__add__。区分self(对象) 和cls(类) 的使用场景。八、课后作业计数器类创建一个Person类每实例化一个对象类属性population加 1。实现一个__del__方法析构函数对象销毁时调用让population减 1。时间类运算完善MyTime类包含hour,minute。实现__add__方法支持两个时间相加注意进位如 1:30 1:40 3:10。单例模式挑战题查阅资料尝试用__new__方法实现一个单例类无论创建多少次都只返回同一个对象。下节预告Day 17异常处理 (Try-Except)- 程序报错了怎么办直接崩溃吗不我们要学会优雅地处理错误让程序坚不可摧。系列导航上一篇Day 15 - 面向对象编程(中)下一篇Day 17 - 异常处理待更新