找回密码
 会员注册
查看: 31|回复: 0

Python魔法之旅-魔法方法(05)

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
69864
发表于 2024-9-10 06:25:24 | 显示全部楼层 |阅读模式
目录一、概述1、定义2、作用二、应用场景1、构造和析构2、操作符重载3、字符串和表示4、容器管理5、可调用对象6、上下文管理7、属性访问和描述符8、迭代器和生成器9、数值类型10、复制和序列化11、自定义元类行为12、自定义类行为13、类型检查和转换14、自定义异常三、学习方法1、理解基础2、查阅文档3、编写示例4、实践应用5、阅读他人代码6、参加社区讨论7、持续学习8、练习与总结9、注意兼容性10、避免过度使用四、魔法方法17、__float__方法17-1、语法17-2、参数17-3、功能17-4、返回值17-5、说明17-6、用法18、__floor__方法18-1、语法18-2、参数18-3、功能18-4、返回值18-5、说明18-6、用法19、__floordiv__方法19-1、语法19-2、参数19-3、功能19-4、返回值19-5、说明19-6、用法五、推荐阅读1、Python筑基之旅2、Python函数之旅3、Python算法之旅4、博客个人主页一、概述1、定义        魔法方法(MagicMethods/SpecialMethods,也称特殊方法或双下划线方法)是Python中一类具有特殊命名规则的方法,它们的名称通常以双下划线(`__`)开头和结尾。        魔法方法用于在特定情况下自动被Python解释器调用,而不需要显式地调用它们,它们提供了一种机制,让你可以定义自定义类时具有与内置类型相似的行为。2、作用        魔法方法允许开发者重载Python中的一些内置操作或函数的行为,从而为自定义的类添加特殊的功能。二、应用场景1、构造和析构1-1、__init__(self,[args...]):在创建对象时初始化属性。1-2、__new__(cls,[args...]):在创建对象时控制实例的创建过程(通常与元类一起使用)。1-3、__del__(self):在对象被销毁前执行清理操作,如关闭文件或释放资源。2、操作符重载2-1、__add__(self,other)、__sub__(self,other)、__mul__(self,other)等:自定义对象之间的算术运算。2-2、__eq__(self,other)、__ne__(self,other)、__lt__(self,other)等:定义对象之间的比较操作。3、字符串和表示3-1、__str__(self):定义对象的字符串表示,常用于print()函数。3-2、__repr__(self):定义对象的官方字符串表示,用于repr()函数和交互式解释器。4、容器管理4-1、__getitem__(self,key)、__setitem__(self,key,value)、__delitem__(self,key):用于实现类似列表或字典的索引访问、设置和删除操作。4-2、__len__(self):返回对象的长度或元素个数。5、可调用对象5-1、__call__(self,[args...]):允许对象像函数一样被调用。6、上下文管理6-1、__enter__(self)、__exit__(self,exc_type,exc_val,exc_tb):用于实现上下文管理器,如with语句中的对象。7、属性访问和描述符7-1、__getattr__,__setattr__,__delattr__:这些方法允许对象在访问或修改不存在的属性时执行自定义操作。7-2、描述符(Descriptors)是实现了__get__,__set__,和__delete__方法的对象,它们可以控制对另一个对象属性的访问。8、迭代器和生成器8-1、__iter__和__next__:这些方法允许对象支持迭代操作,如使用for循环遍历对象。8-2、__aiter__,__anext__:这些是异步迭代器的魔法方法,用于支持异步迭代。9、数值类型9-1、__int__(self)、__float__(self)、__complex__(self):定义对象到数值类型的转换。9-2、__index__(self):定义对象用于切片时的整数转换。10、复制和序列化10-1、__copy__和__deepcopy__:允许对象支持浅复制和深复制操作。10-2、__getstate__和__setstate__:用于自定义对象的序列化和反序列化过程。11、自定义元类行为11-1、__metaclass__(Python2)或元类本身(Python3):允许自定义类的创建过程,如动态创建类、修改类的定义等。12、自定义类行为12-1、__init__和__new__:用于初始化对象或控制对象的创建过程。12-2、__init_subclass__:在子类被创建时调用,允许在子类中执行一些额外的操作。13、类型检查和转换13-1、__instancecheck__和__subclasscheck__:用于自定义isinstance()和issubclass()函数的行为。14、自定义异常14-1、你可以通过继承内置的Exception类来创建自定义的异常类,并定义其特定的行为。三、学习方法        要学好Python的魔法方法,你可以遵循以下方法及步骤:1、理解基础        首先确保你对Python的基本语法、数据类型、类和对象等概念有深入的理解,这些是理解魔法方法的基础。2、查阅文档        仔细阅读Python官方文档中关于魔法方法的部分,文档会详细解释每个魔法方法的作用、参数和返回值。你可以通过访问Python的官方网站或使用help()函数在Python解释器中查看文档。3、编写示例        为每个魔法方法编写简单的示例代码,以便更好地理解其用法和效果,通过实际编写和运行代码,你可以更直观地感受到魔法方法如何改变对象的行为。4、实践应用        在实际项目中尝试使用魔法方法。如,你可以创建一个自定义的集合类,使用__getitem__、__setitem__和__delitem__方法来实现索引操作。只有通过实践应用,你才能更深入地理解魔法方法的用途和重要性。5、阅读他人代码        阅读开源项目或他人编写的代码,特别是那些使用了魔法方法的代码,这可以帮助你学习如何在实际项目中使用魔法方法。通过分析他人代码中的魔法方法使用方式,你可以学习到一些新的技巧和最佳实践。6、参加社区讨论        参与Python社区的讨论,与其他开发者交流关于魔法方法的使用经验和技巧,在社区中提问或回答关于魔法方法的问题,这可以帮助你更深入地理解魔法方法并发现新的应用场景。7、持续学习        ython语言和其生态系统不断发展,新的魔法方法和功能可能会不断被引入,保持对Python社区的关注,及时学习新的魔法方法和最佳实践。8、练习与总结        多做练习,通过编写各种使用魔法方法的代码来巩固你的理解,定期总结你学到的知识和经验,形成自己的知识体系。9、注意兼容性        在使用魔法方法时,要注意不同Python版本之间的兼容性差异,确保你的代码在不同版本的Python中都能正常工作。10、避免过度使用        虽然魔法方法非常强大,但过度使用可能会导致代码难以理解和维护,在编写代码时,要权衡使用魔法方法的利弊,避免滥用。        总之,学好Python的魔法方法需要不断地学习、实践和总结,只有通过不断地练习和积累经验,你才能更好地掌握这些强大的工具,并在实际项目中灵活运用它们。四、魔法方法17、__float__方法17-1、语法__float__(self,/)float(self)17-2、参数17-2-1、self(必须):一个对实例对象本身的引用,在类的所有方法中都会自动传递。17-2-2、/(可选):这是从Python3.8开始引入的参数注解语法,它表示这个方法不接受任何位置参数(positional-onlyparameters)之后的关键字参数(keywordarguments)。17-3、功能    用于定义一个对象到浮点数的转换规则。17-4、返回值        返回一个浮点数。17-5、说明    具体来说,以下几种情况可能会触发__float__方法的调用:17-5-1、使用内置的float函数尝试将一个对象转换为浮点数时。17-5-2、在需要进行数学运算(如加法、减法、乘法、除法等)的上下文中,如果操作数之一是对象,而另一个是浮点数或需要浮点数的操作(如除法),则可能会调用该对象的__float__方法。17-5-3、在需要浮点数类型的其他内置函数或方法中,如果提供了不支持直接操作的对象,可能会调用该对象的__float__方法。17-6、用法#017、__float__方法:#1、简单的数值类#定义一个名为SimpleNumber的类classSimpleNumber:#类的初始化方法,当创建SimpleNumber对象时自动调用def__init__(self,value):#将传入的value参数赋值给对象的value属性self.value=value#定义__float__方法,用于将对象转换为浮点数def__float__(self):#返回self.value的浮点数形式returnfloat(self.value)#如果这个脚本作为主程序运行(而不是被导入为模块)if__name__=='__main__':#创建一个SimpleNumber对象n,并传入值5.2n=SimpleNumber(5.2)#使用内置的float函数和SimpleNumber类的__float__方法将n转换为浮点数f=float(n)#打印转换后的浮点数fprint(f)#输出:5.2#2、分数类(有理数)#定义一个名为Fraction的类,用于表示分数classFraction:#初始化方法,当创建Fraction对象时调用def__init__(self,numerator,denominator):#设置分数的分子self.numerator=numerator#设置分数的分母self.denominator=denominator#定义转换为浮点数的特殊方法def__float__(self):#返回分数的浮点数值(即分子除以分母)returnself.numerator/self.denominator#如果这个脚本作为主程序运行(而不是被导入为模块)if__name__=='__main__':#创建一个Fraction对象f,分子为3,分母为4f=Fraction(3,4)#使用内置的float函数和Fraction类的__float__方法将f转换为浮点数float_f=float(f)#打印转换后的浮点数float_fprint(float_f)#输出:0.75#3、带有单位的度量类(如距离)#定义一个名为Distance的类,用于表示距离classDistance:#初始化方法,用于创建Distance对象时设置距离(以米为单位)def__init__(self,meters):#将传入的距离值(以米为单位)赋值给对象的meters属性self.meters=meters#定义转换为浮点数的特殊方法#当尝试将Distance对象转换为浮点数时,会调用这个方法def__float__(self):#返回Distance对象的meters属性的值,作为浮点数returnself.meters#如果这个脚本作为主程序运行(而不是被导入为模块)if__name__=='__main__':#创建一个Distance对象d,表示100.5米的距离d=Distance(100.5)#使用内置的float函数和Distance类的__float__方法将d转换为浮点数float_d=float(d)#打印转换后的浮点数float_dprint(float_d)#输出:100.5#4、复数类(尽管Python内置了复数类型,但可以作为示例)#定义一个名为MyComplex的类,用于表示复数classMyComplex:#初始化方法,用于创建MyComplex对象时设置实部和虚部def__init__(self,real,imag):#设置实部self.real=real#设置虚部self.imag=imag#定义转换为浮点数的特殊方法#当尝试将MyComplex对象转换为浮点数时,会调用此方法def__float__(self):#如果虚部不为0ifself.imag!=0:#抛出ValueError异常,表示不能将有虚部的复数转换为浮点数raiseValueError("Cannotconvertcomplexnumberwithimaginaryparttofloat")#如果虚部为0,则返回实部的浮点数值returnfloat(self.real)#如果这个脚本作为主程序运行(而不是被导入为模块)if__name__=='__main__':#创建一个实部为3,虚部为0的MyComplex对象cc=MyComplex(3,0)#使用内置的float函数和MyComplex类的__float__方法将c转换为浮点数f=float(c)#打印转换后的浮点数fprint(f)#输出:3.0try:#创建一个实部为3,虚部为4的MyComplex对象c_with_imagc_with_imag=MyComplex(3,4)#尝试将c_with_imag转换为浮点数,但由于虚部不为0,所以会抛出ValueError异常float_c_with_imag=float(c_with_imag)#这会抛出ValueErrorexceptValueErrorase:#捕获ValueError异常并打印异常信息print(e)#输出:Cannotconvertcomplexnumberwithimaginaryparttofloat#5、时间类(转换为以秒为单位的浮点数)#从datetime模块中导入timedelta类,timedelta类用于表示两个日期或时间之间的差异fromdatetimeimporttimedelta#定义一个名为TimeDuration的类,用于封装timedelta并允许通过不同的时间单位进行初始化classTimeDuration:def__init__(self,days=0,seconds=0,microseconds=0,milliseconds=0,minutes=0,hours=0,weeks=0):#因为timedelta不接受milliseconds参数,并且weeks参数需要转换为days,所以我们先进行计算#将weeks转换为days(1周=7天)#注意:在Python3中,timedelta直接支持weeks参数,但在Python2中不支持td=timedelta(days=days+weeks*7,seconds=seconds,microseconds=microseconds,minutes=minutes,hours=hours)#如果提供了毫秒(milliseconds),则需要将其转换为秒和微秒#注意:这里我们省略了毫秒的转换,因为timedelta不接受毫秒作为直接参数#如果需要,可以在此添加转换逻辑#将计算好的timedelta赋值给实例的duration属性self.duration=td#定义转换为浮点数的特殊方法,返回时间差的总秒数def__float__(self):#调用辅助函数total_seconds来获取duration的总秒数#注意:在Python3中,timedelta有一个total_seconds()方法,但在Python2中没有returntotal_seconds(self.duration)#辅助函数,用于计算timedelta对象的总秒数#在Python2中,timedelta没有直接的total_seconds方法,所以我们自己实现deftotal_seconds(td):#计算总秒数,包括天、小时、分钟、秒和微秒return(td.microseconds+(td.seconds+td.days*24*3600)*1e6)/1e6if__name__=='__main__':#创建一个TimeDuration对象,表示1天2小时30分钟的时间差td=TimeDuration(days=1,hours=2,minutes=30)#使用内置的float函数和TimeDuration类的__float__方法将td转换为浮点数(总秒数)float_td=float(td)#打印转换后的总秒数print(float_td)#输出:95400.0(具体取决于你的系统时间精度,但在这个例子中应该是准确的)#6、字符串表示的数字转换为浮点数#定义一个名为StringNumber的类,用于将字符串表示的数字转换为浮点数classStringNumber:#初始化方法,接收一个字符串类型的数字作为参数def__init__(self,number_str):#将接收到的字符串类型的数字保存到实例变量number_str中self.number_str=number_str#定义转换为浮点数的特殊方法#当尝试将StringNumber对象转换为浮点数时,会调用此方法def__float__(self):#使用Python内置的float函数将number_str转换为浮点数#并返回这个浮点数returnfloat(self.number_str)#判断当前脚本是否作为主程序运行(而不是被导入为模块)if__name__=='__main__':#创建一个StringNumber对象,传入一个表示数字的字符串"3.14159"sn=StringNumber("3.14159")#使用内置的float函数和StringNumber类的__float__方法将sn转换为浮点数#注意:这里实际上不需要显式调用float(sn),因为当sn被用于需要浮点数的上下文中时,#Python会自动调用sn的__float__方法。但为了展示和明确转换,这里显式调用了float(sn)f=float(sn)#打印转换后的浮点数print(f)#输出:3.14159'运行运行18、__floor__方法18-1、语法__floor__(self,/)FlooringanIntegralreturnsitself18-2、参数18-2-1、self(必须):一个对实例对象本身的引用,在类的所有方法中都会自动传递。18-2-2、/(可选):这是从Python3.8开始引入的参数注解语法,它表示这个方法不接受任何位置参数(positional-onlyparameters)之后的关键字参数(keywordarguments)。18-3、功能        用于定义数值类型的“向下取整”行为。18-4、返回值    返回不大于对象所表示数值的最大整数,也就是所谓的“向下取整”或“地板除”的结果。18-5、说明        关于返回值,__floor__方法应该返回一个与原始对象相同类型或兼容类型的对象,其值是不大于原始对象所表示数值的最大整数。18-6、用法#018、__floor__方法:#1、基本使用#定义一个名为MyNumber的类,用于封装一个数值并提供一些特殊方法classMyNumber:#类的初始化方法,用于创建MyNumber类的实例def__init__(self,value):#将传入的value参数赋值给实例变量self.valueself.value=value#定义一个特殊方法__floor__,用于返回self.value的向下取整值def__floor__(self):#导入math模块,尽管在类中导入模块不是最佳实践,但这里为了注释而保留importmath#调用math.floor方法对self.value进行向下取整,并返回结果returnmath.floor(self.value)#当这个脚本作为主程序运行时,以下代码块会被执行if__name__=='__main__':#创建一个MyNumber类的实例num,并传入初始值3.7num=MyNumber(3.7)#调用num实例的__floor__方法,并打印返回的结果,即3.7的向下取整值print(num.__floor__())#输出:3#2、自定义运算符中的使用#导入math模块,该模块包含了一些数学运算的函数和常量importmath#定义一个名为MyNumber的类,用于封装数值并提供自定义的数学运算classMyNumber:#初始化方法,用于创建MyNumber对象时设置初始值def__init__(self,value):self.value=value#将传入的value赋值给对象的value属性#定义一个特殊方法__floor__,用于返回对象的value属性的向下取整值def__floor__(self):returnmath.floor(self.value)#使用math模块中的floor函数对value进行向下取整#定义一个特殊方法__int__,用于将MyNumber对象转换为整数def__int__(self):returnint(self.value)#定义__int__方法以返回整数值,这里将value转换为整数并返回#定义一个特殊方法__add__,用于实现MyNumber对象之间的加法运算def__add__(self,other):ifisinstance(other,MyNumber):#如果other也是MyNumber对象returnMyNumber(self.value+other.value)#返回两个对象value属性之和组成的新MyNumber对象else:#如果other不是MyNumber对象returnMyNumber(self.value+other)#返回对象value属性与other之和组成的新MyNumber对象#定义一个特殊方法__floordiv__,用于实现MyNumber对象之间的整数除法运算def__floordiv__(self,other):ifisinstance(other,MyNumber):#如果other也是MyNumber对象floored_self=self.__floor__()#对self的value属性进行向下取整floored_other=other.__floor__()#对other的value属性进行向下取整returnMyNumber(floored_self//floored_other)#返回两个向下取整后的值进行整除运算的结果组成的新MyNumber对象else:#如果other不是MyNumber对象returnMyNumber(self.__floor__()//other)#对self的value属性进行向下取整,然后与other进行整除运算,返回结果组成的新MyNumber对象#当这个脚本作为主程序运行时,以下代码块会被执行if__name__=='__main__':#创建两个MyNumber对象num1和num2,并分别设置初始值7.3和2num1=MyNumber(7.3)num2=MyNumber(2)#使用//运算符调用num1的__floordiv__方法,与num2进行整数除法运算,并打印结果print(num1//num2)#使用__floordiv__,输出:MyNumber(3)#将num1和num2进行整数除法运算的结果转换为整数并打印print(int(num1//num2))#现在可以正确转换为整数,输出:3#3、在类中自动转换#定义一个名为MyNumber的类,用于封装数值并提供一些特殊方法classMyNumber:#类的初始化方法,用于设置对象的初始值def__init__(self,value):#将传入的value参数赋值给对象的value属性self.value=value#定义一个特殊方法__floor__,用于返回对象value属性的向下取整值def__floor__(self):#导入math模块,该模块包含数学相关的函数importmath#调用math模块中的floor函数对value进行向下取整,并返回结果returnmath.floor(self.value)#定义一个特殊方法__int__,用于将对象转换为整数类型def__int__(self):#调用__floor__方法获取value的向下取整值#然后将该值转换为整数类型并返回returnint(self.__floor__())#当这个脚本作为主程序运行时,以下代码块会被执行if__name__=='__main__':#创建一个MyNumber对象num,并传入初始值3.7num=MyNumber(3.7)#调用num对象的__int__方法,将其转换为整数类型并打印结果#这里通过内置的int函数间接调用了num的__int__方法print(int(num))#输出:3#4、类的继承与重写#定义一个名为MyNumber的类,用于封装数值并提供向下取整的方法classMyNumber:#类的初始化方法,用于设置对象的初始值def__init__(self,value):#将传入的value参数赋值给对象的value属性self.value=value#定义一个特殊方法__floor__,用于返回对象value属性的向下取整值def__floor__(self):#导入math模块(虽然通常建议在文件顶部导入,但这里为了说明也可在方法内部导入)importmath#调用math模块中的floor函数对value进行向下取整,并返回结果returnmath.floor(self.value)#定义一个特殊方法__int__,用于将对象转换为整数类型def__int__(self):#调用__floor__方法获取value的向下取整值#然后将该值转换为整数类型并返回returnint(self.__floor__())#定义一个继承自MyNumber的SpecialNumber类classSpecialNumber(MyNumber):#重写父类MyNumber的__floor__方法def__floor__(self):#使用super()函数调用父类MyNumber的__floor__方法#然后将返回的结果减1,得到SpecialNumber对象的特殊向下取整值returnsuper().__floor__()-1#当这个脚本作为主程序运行时,以下代码块会被执行if__name__=='__main__':#创建一个SpecialNumber对象num,并传入初始值4.3num=SpecialNumber(4.3)#调用num对象的__int__方法,将其转换为整数类型并打印结果#这里通过内置的int函数间接调用了num的__int__方法#SpecialNumber类重写了__floor__方法,所以其__int__方法返回的是特殊向下取整后的整数值print(int(num))#输出:3,因为4.3向下取整是4,然后减1得到3#5、与其他类型进行比较#定义一个名为MyNumber的类,用于封装数值并提供一些特殊方法classMyNumber:#类的初始化方法,用于设置对象的初始值def__init__(self,value):#将传入的value参数赋值给对象的value属性self.value=value#定义一个特殊方法__floor__,用于返回对象value属性的向下取整值def__floor__(self):#导入math模块(尽管通常在文件顶部导入模块,但在此为了注释说明也可以放在方法内部)importmath#调用math模块中的floor函数对value进行向下取整,并返回结果returnmath.floor(self.value)#定义一个特殊方法__eq__,用于比较两个对象是否相等def__eq__(self,other):#如果other是整数类型ifisinstance(other,int):#则比较MyNumber对象的向下取整值是否等于otherreturnself.__floor__()==other#如果other不是整数类型,则返回NotImplemented,表示不支持该类型的比较#这样可以让Python尝试进行其他类型的比较(如other也是MyNumber对象)returnNotImplemented#当这个脚本作为主程序运行时,以下代码块会被执行if__name__=='__main__':#创建一个MyNumber对象num,并传入初始值3.0num=MyNumber(3.0)#使用==操作符比较num对象和整数3是否相等#由于num的value是3.0,向下取整后仍为3,所以比较结果为Trueprint(num==3)#输出:True#6:自定义格式化输出#定义一个名为MyNumber的类classMyNumber:#类的初始化方法,用于创建MyNumber类的实例def__init__(self,value):#将传入的value赋值给实例变量self.valueself.value=value#定义一个特殊方法__floor__,它用于实现取整(向下取整)的功能def__floor__(self):#导入math模块(尽管这里最好是在文件顶部导入,但为了符合仅注释代码的要求,这里也可以接受)importmath#使用math.floor方法对self.value进行向下取整,并返回结果returnmath.floor(self.value)#定义一个特殊方法__format__,它允许对象自定义其字符串表示形式#format_spec是格式说明符,它描述了如何格式化对象def__format__(self,format_spec):#如果格式说明符为'.floor',则调用__floor__方法并返回其结果的字符串形式ifformat_spec=='.floor':returnstr(self.__floor__())#如果格式说明符不是'.floor',则返回NotImplemented,表示不支持该格式returnNotImplemented#如果当前运行的脚本(而不是导入的模块)是主程序,则执行以下代码if__name__=='__main__':#创建一个MyNumber类的实例num,并传入值3.7num=MyNumber(3.7)#使用format函数和'.floor'格式说明符来格式化num对象,并打印结果#由于MyNumber类定义了__format__方法并处理了'.floor'格式说明符,因此这里会输出'3'print(format(num,'.floor'))#输出:'3''运行运行19、__floordiv__方法19-1、语法__floordiv__(self,other,/)Returnself//other19-2、参数19-2-1、self(必须):一个对实例对象本身的引用,在类的所有方法中都会自动传递。19-2-2、other(必须):表示与self进行地板除法的另一个值,它可以是任何类型,但通常应该是与self兼容的数值类型。19-2-3、/(可选):这是从Python3.8开始引入的参数注解语法,它表示这个方法不接受任何位置参数(positional-onlyparameters)之后的关键字参数(keywordarguments)。19-3、功能        用于定义当对象使用//运算符进行地板除法时的行为。19-4、返回值        返回一个表示地板除法结果的对象。19-5、说明        对于__floordiv__方法,它的返回值通常是与原始对象类型相同或兼容的数值类型对象,其值是两个操作数进行地板除法的结果,然而,这个返回值的具体类型完全取决于你的实现。19-6、用法#019、__floordiv__方法:#1、简单的整数类classSimpleInt:def__init__(self,value):#初始化方法,设置实例的value属性self.value=valuedef__floordiv__(self,other):#定义地板除法运算符的行为ifisinstance(other,(int,float)):#如果other是整数或浮点数,则执行地板除法并返回结果returnself.value//otherelse:#如果other不是整数或浮点数,则抛出类型错误raiseTypeError("Unsupportedoperandtype(s)for//:'SimpleInt'and'{}'".format(type(other).__name__))if__name__=='__main__':#创建一个SimpleInt类的实例a,并设置其值为10a=SimpleInt(10)#定义一个普通的整数b,其值为3b=3#使用//运算符调用a的__floordiv__方法,并打印结果#这里将输出整数3,因为10//3的结果是3print(a//b)#这会调用SimpleInt的__floordiv__方法,输出应为3#2、自定义除法规则类classCustomDiv:def__init__(self,value):#初始化方法,设置实例的value属性self.value=valuedef__floordiv__(self,other):#地板除法特殊方法,用于处理自定义除法规则ifisinstance(other,int):#检查other是否为整数#如果self.value是非负数,则执行正常的地板除法(即减去余数)#如果self.value是负数,则先取负数的绝对值进行整除,再取负值(因为负数的整除行为是向负无穷方向取整)returnself.value-(self.value%other)ifself.value>=0else-((-self.value)//other)else:#如果other不是整数,则抛出类型错误raiseTypeError("Unsupportedoperandtype(s)for//:'CustomDiv'and'{}'".format(type(other).__name__))if__name__=='__main__':#创建一个CustomDiv实例,并设置其value为10cd=CustomDiv(10)#调用CustomDiv的__floordiv__方法(即执行cd//3),并打印结果#因为10>=0,所以直接执行self.value-(self.value%other),即10-(10%3)=10-1=9print(cd//3)#输出:9#直接使用类名和参数创建另一个CustomDiv实例,其value为-10#调用该实例的__floordiv__方法(即执行CustomDiv(-10)//3),并打印结果#因为-10
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 06:41 , Processed in 1.149659 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表