解密面向对象三大特征:封装、继承、多态
一、面向对象基本概念
类:用几大特征表述一一类事物。类要表达的是一个抽象的概念。
对象:对象是类的具体实现。举个例子,类像是一张图纸,对象是由这张图纸产出的具体物品。类只有一个,但是对象可以同这个类实例出多个。
对象是类的实例,类是对象的模板。
类中的成员只有属性和方法,不要裸露地把判断和循环写在类中,而要用方法包起来。
面向对象的本质就像「搭乐高」:
每个积木块都是独立的小机器人(对象)
有自己专属的技能(方法)
携带自己的工具包(属性)
比如「汽车积木」自己会跑、有四个轮子
积木之间通过标准接口互相连接
不需要知道对方内部怎么运作
只要说「帮我运货」,卡车积木就会自动完成任务
可以批量生产相似机器人
用「机器人模具」(类)造出一模一样的
还能给模具加新功能(继承)
比如给「动物模具」加翅膀,立刻生成会飞的动物
同一个指令能触发不同反应
对所有积木喊「干活」,有的扫地、有的做饭(多态)
每个积木按自己的方式响应
最终效果:用现实世界的思维方式,把复杂系统拆解成互相协作的智能模块,像指挥机器人战队一样写程序。
1.1类的定义
class Car:pass#推荐使用下面定义方式
class Car():pass
class Car(object):pass
1.2类的实例化
class Car():pass
#类的实例化,实例化对象,new新对象
obj=Car()
1.3类的基本结构
#类中只有成员属性和成员方法
class Car():#成员属性color="咖啡色"#成员方法defrun():print("fast")
1.4类的命名
类的命名推荐使用驼峰命名法,如:
MyCar,MaHuaTeng;
1.5对象、类的相关操作
1.5.1成员等级
python对成员的保护分为两个等级:
私有的(private):在本类内部可以访问,类的外部不可以访问。(python中属性或者方法前面加两个下划线"_")
公有的(public):在本类的内部和外部都可以访问。
受保护的(protect)(了解)在其他高级语言中,如java,php,c++等语言,有三个等级:private,public,protected。不能够继承的。
1.5.2对象的相关操作
(1)实例化的对象访问公有成员属性和方法 (2)实例化的对象动态添加公有成员属性和方法 (3)实例化的对象删除公有成员属性和方法
#Part01实例化的对象访问公有成员属性和方法 """ 对象的语法:对象.属性对象.方法()绑定方法:(1)绑定到对象(调用方法时候,自动把对象当成参数进行传递)(2)绑定到类(调用方法时候,自动把类当成参数进行传递) """ classMyCar():#公有成员属性color="咖啡色" #私有成员属性__logo="特斯拉"#公有成员方法defrun(self):print("我的小车爬起来很快",self.color) #私有成员方法 def__info(self):print("我的价格保密,类外不能调用") #类的实例化 obj=MyCar() #对象的相关操作 #(1)实例化的对象访问公有成员属性和方法 print(obj.color) #obj.__logoerror不能在类外调用私有成员 """ 当对象.方法的时候,系统会自动把前面的对象当成参数进行传递, 传递给self这个形参来进行接收,self是约定俗称的名字,代表本对象 """ obj.drive() #Part02实例化的对象动态添加公有成员属性和方法 #添加成员属性 obj.luntai="米其林" print(obj.luntai) #__dict__查看类或对象的成员结构,返回一个字典 print(obj.__dict__) """ color__logodrive__info它们都归属于MyCar这个类的 对象可以使用类中的公有成员,但是没有归属权; """ #添加成员方法(在类外动态添加方法,默认需要手动传递参数;) #(1)动态添加无参方法 def dahuangfeng():print("请叫我大黄蜂,我的车会变形") obj.dahuangfeng=dahuangfeng obj.dahuangfeng() #(2)动态添加有参方法 defqingtianzhu(name):print("请叫我"+name+",我的车会变形") obj.qingtianzhu=qingtianzhu obj.qingtianzhu("擎天柱") #升级 def qingtianzhu(self,name):print("请叫我"+name+",我的车会变形",self.color) #qingtianzhu(obj,"擎天柱") obj.qingtianzhu2=qingtianzhu obj.qingtianzhu2(obj,"擎天柱") #利用types改造MethodType(相应的函数,要绑定的对象) importtypes #通过MethodType来创建一个绑定方法,赋值给成员qingtianzhu3 obj.qingtianzhu3=types.MethodType(qingtianzhu,obj) #绑定方法意味着在调用时,系统会自动把该对象作为参数进行传递 obj.qingtianzhu3("擎天柱3") #(3)动态添加lambda匿名函数 obj.fadongji=lambda:print("我是制造发动机的方法") obj.fadongji() #part03实例化的对象删除公有成员属性和方法 #删除属性del对象.属性 delobj.oil #print(obj.oil)error #删除方法del类.方法 delobj.oil_info #obj.oil_infoerror
1.5.3类的相关操作
(1)定义的类访问公有成员属性和方法 (2)定义的类动态添加公有成员属性和方法 (3)定义的类删除公有成员属性和方法
#part01定义的类访问公有成员属性和方法 classMyCar():#公有成员属性oil="2.0T"#私有成员属性__price="1亿"#公有的无参方法defoil_info():print("我的油耗信息",MyCar.__price)#私有的无参方法def__price_info():print("我的价格信息")""" #实例化对象 obj=MyCar() #对象无法调用无参的公有方法 obj.oil_info() """ #(1)定义的类访问公有成员属性和方法 print(MyCar.oil) #print(MyCar.__price)error无论是对象还是类,都无法在类外调用私有成员; MyCar.oil_info() #part02定义的类动态添加公有成员属性和方法 #添加公有成员属性 MyCar.logo="宝马" print(MyCar.logo) print(MyCar.__dict__) #添加公有成员方法 #(1)动态添加公有无参方法 def fangxiangpan():print("制造方向盘的方法") MyCar.fangxiangpan=fangxiangpan MyCar.fangxiangpan() #(2)动态添加公有的有参方法 def cardoor(something):print("我的车门是{}制作的".format(something)) MyCar.cardoor=cardoor MyCar.cardoor("铝合金") #(3)动态添加lambda表达式 MyCar.tianchuang=lambdan:print("制造{}的一个方法".format(n)) MyCar.tianchuang("天窗") print(MyCar.__dict__) """ 类中的成员只归属于当前这个类, 对象可以调用其中的公有成员,但是没有修改和删除的权利,因为归属于类 类无法调用对象中的相关成员,但是对象可以调用类中的相关成员; 对象调用成员时,先看看自己有没有该成员,如果有直接调用,如果没有调用类; """ #例子 obj=MyCar() #obj.fangxiangpan() #对象可以调用类中的公有成员属性方法 obj.cardoor() #类可以调用对象中的公有成员么?不可以! '''调用对象中的成员时,先看看自己有没有该成员,如果有直接调用,如果没有调用类的;''' #obj.oil="1.5T" #print(obj.oil) #print(MyCar.oil) #obj.oil222="3.0T" #print(MyCar.oil222) #part03定义的类删除公有成员属性和方法 #删除属性del类.属性 delMyCar.oil #print(MyCar.oil)error #删除方法del类.方法 delMyCar.oil_info #MyCar.oil_infoerror
1.5.4方法
普通方法:没有任何参数传递,只能类调用
绑定方法:把默认传参的方法叫做绑定方法,绑定到对象(默认传对象),绑定到类(默认传类)
非绑定方法:静态方法(无需传任何参数,对象和类都能调用)
1.5.5类中的私有成员调用方法
(1)利用类调用公有方法调用私有成员(推荐) (2))利用对象调用公有方法调用私有成员
class Plane():#公有成员属性captain="机长"#私有成员属性__airsistant=2 #公有绑定方法 def fly1(self):print("飞的贼快") #公有普通无参方法 def fly2():print("飞的贼高") #私有绑定方法 def__plane_info(self):print("飞机上的空姐数量是保密的",self.__airsistant) #私有普通方法 def__plane_info2():print("飞机上的空姐很好看") #用对象调用公有方法(绑定到对象)pub_info间接实现对私有成员的调用 def pub_info(self):print(self.__airsistant)self.__plane_info() #用类调用公有方法pub_info2间接实现对私有成员的调用(推荐使用!!) def pub_info2():print(Plane.__airsistant)Plane.__plane_info2() #实例化对象 obj=Plane() #1.类调用 Plane.pub_info2() #2.对象调用 obj.pub_info()
1.5.6私有成员的命名策略
#私有成员的命名策略:_类+私有成员就是该成员的真实名字(不推荐使用) print(obj._Plane__airsistem) #obj._Plane__plane_info() print(Plane._Plane__airsistem) #Plane._Plane__plane_info2()
二、面向对象三大特征
(1)封装:对类中成员属性和成员方法的保护,控制外界对内部成员的访问,修改,删除等操作; (2)继承:一个类除了自身所拥有的属性和方法之外,还获取了另外一个类的属性和方法; (3)多态:不同的子对象,调用相同的父类方法,产生了不同的执行结果;
2.1封装
参考本文1.5节相关内容。
2.2继承
一个类继承另外一个类,那么该类就是子类(衍生类),被继承的这个类叫做父类(超类,基类)
继承:
(1)单继承(2)多继承
python3中所有的类都默认继承父类object
2.2.1单继承
(1)子父继承之后,子类可以调用父类的公有的属性和方法
(2)子父继承之后,子类不可以调用父类的私有成员
(3)子父继承之后,子类可以改写父类的方法
(4)子父继承之后,子类优先调用自己的成员属性方法,如果没有则调用父类的属性方法,如果都没有,直接报错
class Human():hair="黄色的"__age=18def eat(self):print("人类天生就会吃,吃猎物")def la(self):print("人类天生就会上厕所")def__makebaby(self):print("人类可以繁衍后代")
#(1)子父继承之后,子类可以调用父类的公有的属性和方法
class Man(Human):pass
obj=Man()
print(obj.hair)
#(2)子父继承之后,子类不可以调用父类的私有成员
class Woman(Human):defpub_func(self): self.__ageself.__makebaby()obj=Woman()
#obj.__makebaby()error
#obj.pub_func()
#(3)子父继承之后,子类可以改写父类的方法
"""
子父继承之后,
如果子类里面有该成员属性方法,优先调用自己的,
如果没有该成员属性方法,那么调用父类的属性方法
如果都没有,直接报错;
"""
class Children(Human):defeat(self):print("小孩天生只会喝奶奶")obj=Children()
obj.eat()
2.2.2多继承
super的用法: (1)super本身是一个类,super()是一个对象,用于调用父类的绑定方法 (2)super()只应用在绑定方法中,默认自动传递self对象(前提:super所在作用域存在self) (3)super用途:解决复杂的多继承调用关系
class Father():property="抽烟喝酒"deff_hobby():print("出去喜欢抽烟喝酒")
class Mother():property="化妆品包包"defm_hobby(self):print("逛街买化妆品包包")
class Son(Father,Mother):property="打游戏看直播"#1.利用类来调用父类的属性和方法defskill1(self):Father.f_hobby()print(Mother.property)
#2.利用对象调用父类的属性和方法#self在调用父类方法属性的时候,在本类有的时候,先调用自己的,如果没有,再调用父类的def skill2(self):self.m_hobby()#无,调用父类print(self.property)#有,调用自身#3.利用super调用父类的属性和方法#super()只调用父类的相关公有成员,不会调用自己本类中的公有成员,super()特指调用父类,跟self有区别def skill3(self):print(super().property)#多个父类,按顺序继承super().m_hobby()#只应用在绑定方法中
self和super区别(****):
当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用super时,则从父类的方法列表中开始找,然后调用父类的这个方法。
2.2.3菱形继承
多继承的弊端会造成菱形继承这种情况,照不清调用顺序
super对象按照mro列表的顺序依次调用,解决菱形继承存在问题
新式类:广度优先(python3.x)
经典类:深度优先(python2.x)
写多继承时,尽量避免造成不同类相同方法名的情况,提高代码质量,实现"高内聚,低耦合"
高内聚:一个模块只完成一个任务,专一性高
低耦合:模块与模块之间可以彼此独立不冲突,方便移植复用
""" Human ManWoman Children """ class Human():pty=444def feelT(self):print("原始人类天热了,脱光1")print(self.pty)print("原始人类天冷了,烤火2")class Man(Human):pty=333def feelT(self):print("男人天冷了,洗澡3")super().feelT()print("男人天热了,洗澡4")class Woman(Human):pty=222def feelT(self):print("女人天冷了,喝热水5")super().feelT()print("女人天热了,喝冷水6")class Children(Man,Woman):pty=111def feelT(self):print("小孩天冷了,睡一觉7")super().feelT()print("小孩天热了,睡一觉8") obj=Children() obj.feelT() """ self.pty打印的值是111, 因为在super().feelT的时候,默认传递的对象,是Children实例化出来的对象.最后传到最上层Human这个类当中,进行调用打印111; Children->Man->Woman->Human """ #mro列表:语法类.mro()返回的是继承调用关系列表;针对于多继承,解决同名方法的调用顺序;内部用的c3算法; #super()就是按照mro()呈现出来的调用顺序列表,依次的进行调用 lst=Children.mro() print(lst) """ [ <class'__main__.Children'>, <class'__main__.Man'>, <class'__main__.Woman'>, <class'__main__.Human'>, <class'object'> ] """ #issubclass判断是否存在子父关系(只要在一个继承链上,有血缘关系即可;) res=issubclass(Children,Man) res=issubclass(Children,Woman) res=issubclass(Children,Human) res=issubclass(Children,(Man,Woman,Human)) print(res) #isinstance判断是否为实例(只要在一个继承链上,有血缘关系即可;) res=isinstance(obj,Children) res=isinstance(obj,Man) res=isinstance(obj,(Human,Woman)) print(res)
issubclass和isinstance对比:
issubclass:判断两个类是否是同类或者在同一继承链上
isinstance:判断一个实例是否为一个类或该子类的实例
相同点:都能判断是否有继承关系
不相同:insubclass用于判断两个类的继承关系,而isinstance用于判断实例化
2.3多态
概念:不同的子类对象,调用相同的父类方法,产生了不同的执行效果
关键字:继承,改写
多态作用:在不改写父类代码的前提下,能实现不同的效果
class Soldier():#攻击defattack(self):pass#撤退defback(self):pass #陆军 class Army(Soldier): def attack(self):print("[陆军]上来拼刺刀,你捅我我捅你,一刀999级")def back(self):print("[陆军]撒腿就跑") #海军 class Navy(Soldier):def attack(self):print("[海军]上来就扔鱼叉子,插死一个算一个")def back(self):print("[海军]直接跳海,下海喂鱼")#空军 class AirForce(Soldier):def attack(self):print("[空军]打飞机,用二营长的意大利跑射击") def back(self):print("[空军]原地跳伞,落地成盒")#实例化陆军,产生士兵对象 obj_army=Army() #实例化海军,产生士兵对象 obj_navy=Navy() #实例化空军,产生士兵对象 obj_airforce=AirForce() #各就位准备针对于对象; lst=[obj_army,obj_navy,obj_airforce] #让将军下令指挥 """ 1.全体出击 2.全体撤退 3.空军上,其他人迅速撤离 4.按4退出 """ sign=True whilesign:num=int(input("将军请下令:"))foriinlst:ifnum==1:i.attack()elifnum==2:i.back()elifnum==3:#isinstance判断对象的类型ifisinstance(i,AirForce):i.attack()else:i.back()elifnum=="4":print("谢谢将军的指挥,您辛苦了")sign=Falsebreakelse:print("报告:风太大,没听清楚,麻烦再说一遍!")break
三、魔术方法
魔术方法:特定时机自动触发
3.1__init__魔术方法(****)
#__init__魔术方法(构造方法) '''触发时机:实例化对象,初始化的时候触发功能:为对象添加成员参数:参数不固定,至少一个self参数返回值:无 ''' classChildren():def__init__(self,name,skin):self.name=nameself.skin=skindefcry(self):print("小孩下生就哭")defdrink(self):print("小孩一下生就喜欢喝奶奶")def__baobao(self):print("小孩下生要抱抱~")defpub_func(self):self.__baobao() defobj_info(self):print("该对象的名字是{},该对象的肤色是{}".format(self.name,self.skin)) obj=Children("王钢蛋","黑色") obj.cry() obj.obj_info()3.2__new__魔术方法(****)
#__new__魔术方法 '''触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)功能:控制对象的创建过程参数:至少一个cls接受当前的类,其他根据情况决定返回值:通常返回对象或None ''' #(1)基本语法 classMyClass():a=1 obj_other=MyClass() classMyClass1():def__new__(cls):print(cls)#MyClass1#借助父类object里面__new__魔术方法,把对应的参数类传递进来,就会对应为当前这个类创建对象#obj=object.__new__(cls)#不返回任何对象,None#返回自己本类对象#returnobj#返回其他类对象returnobj_other obj=MyClass1() print(obj)#<__main__.MyClassobjectat0x000002911AB679E8> #(2)__new__和__init__方法对比 """ __new__用来创建对象 __init__用来初始化对象 先创建对象,再初始化对象,所以__new__要快于__init__ __new__和__init参数个数要一一对应 """ #一个参数 classBoat():def__new__(cls,name):returnobject.__new__(cls) def__init__(self,name):print(name) obj=Boat("吴彦祖")#吴彦祖 #多个参数 classBoat():def__new__(cls,*args,**kwargs):returnobject.__new__(cls) def__init__(self,*args,**kwargs):print(args)print(kwargs) obj=Boat("吴彦祖",1,2,name="吴彦祖") #('吴彦祖',1,2) #{'name':'吴彦祖'} #注意点:如果返回的不是自己本类对象,那么不会触发__init__构造方法 classBoat():def__new__(cls,*args,**kwargs):returnobj_other#returnNone def__init__(self):print("构造方法被触发") obj=Boat() #无任何输出
3.3单态(例)模式(****)
单态(例)模式:无论实例化多少次,都有且只有一个对象;
目的:为了节省内存空间,仅仅是单纯利用对象调用相关成员,不需要动态添加属性方法,用单态模式即可;
#(1)基本语法 #经典单例模式代码,必须掌握!!! classSingleton():__obj=Nonedef__new__(cls):ifcls.__obj==None:cls.__obj==object.__new__(cls)returncls.__obj""" 第一次在进行实例化的时候cls.__objisNone为真,所以执行代码块;通过父类创建好对象,赋值给cls.__obj returncls.__obj 第二次进行实例化的时候cls.__objisNone为假,不执行对应代码块,直接returncls.__obj 第三次进行实例化的时候cls.__objisNone为假,不执行对应代码块,直接returncls.__obj 把obj变成私有成员为了防止用户在类外直接调用该成员,形成一种保护; """ obj1=Singleton() obj2=Singleton() obj3=Singleton() print(obj1isobj2)#True print(obj1,obj2,obj3)#id相同 #(2)单例模式+__init__ ```python classSingleton():__obj=Nonedef__new__(cls,*args,**kwags): ifcls.__objisNone:cls.__obj=object.__new__(cls) returncls.__objdef__init__(self,name):self.name=name obj1=Singleton("赵丽颖") obj2=Singleton("杨幂") #无论实例多少次都是同一个对象 print(obj1.name)#杨幂 print(obj2.name)#杨幂3.4__del__魔术方法(****)
#__del__魔术方法(析构方法) '''触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量2.所有对象被del的时候] 功能:对象使用完毕后资源回收参数:一个self接受对象返回值:无 ''' classLangDog():food="吃肉"def__init__(self,name):self.name=namedef__del__(self):print("析构方法被触发了..")#(1)页面执行完毕回收所有变量 obj=LangDog("辛巴") print(obj.name) #(2)所有对象被del的时候 obj2=obj print(objisobj2) print("<==start==>") delobj delobj2 print("<==end==>") #用析构方法模拟文件读取操作 """ fp=open("ceshi.txt",mode="w",encoding="utf-8") fp.write("112344") fp.close() fp=open("ceshi.txt",mode="r",encoding="utf-8") res=fp.read() print(res) fp.close() """ importos classReadFile(object):def__new__(cls,filename):#创建ReadFile的对象 #判断文件是否存在ifos.path.exists(filename):returnobject.__new__(cls)else: returnprint("该文件不存在") def__init__(self,filename):#打开文件操作self.fp=open(filename,mode="r",encoding="utf-8")defreadcontent(self):#读取文件操作content=self.fp.read()returncontentdef__del__(self):#关闭文件操作self.fp.close() #存在这个文件的时候,可以调用readcontent obj=ReadFile("ceshi.txt") print(obj) res=obj.readcontent() print(res) #不存在这个文件的时候,直接报错; obj=ReadFile("ceshisadfsadf'.txt") print(obj) obj.readcontent()
3.5__call__魔术方法(*)
#__call__魔术方法 '''触发时机:把对象当作函数调用的时候自动触发功能:模拟函数化操作参数:参数不固定,至少一个self参数返回值:看需求 ''' #(1)基本用法 classMyClass():def__call__(self):print("call魔术方法被触发")obj=MyClass() obj()#call魔术方法被触发 #(2)模拟洗衣服的过程 classWash():#用call魔术方法做统一的调用def__call__(self,something):self.step1(something)self.step2(something)self.step3() defstep1(self,something):print("把{}泡在盆里面".format(something))defstep2(self,something):print("弄点蓝月亮,吊牌,汰渍泡在{}中搓一搓".format(something))defstep3(self):print("扭干净,晒一下,穿上")obj=Wash() obj("裤衩") ''' 把裤衩泡在盆里面 弄点蓝月亮,吊牌,汰渍泡在裤衩中搓一搓 扭干净,晒一下,穿上 ''' #(3)模拟内置方法int实现myint #int("345")345"234"3.14TrueFalse #boolintfloatstr importmath classMyInt(): #计算最终的结果defmycalc(self,num,sign=1):#去掉左边所有多余的0strvar=num.lstrip("0")#如果传递的是"0000"就强制给它0ifstrvar=="":return0#计算最终的数字结果returneval(strvar)*signdef__call__(self,num):ifisinstance(num,bool):ifnum==False:return0else:return1elifisinstance(num,int):returnnumelifisinstance(num,float):ifnum>0:returnmath.floor(num)else:returnmath.ceil(num)elifisinstance(num,str):if(num[0]=="+"ornum[0]=="-")andnum[1:].isdecimal():#sign用来控制正负号ifnum[0]=="+":sign=1else:sign=-1 #计算结果returnself.mycalc(num[1:],sign)elifnum.isdecimal():returnself.mycalc(num)else:return"老弟,这个也算不了"else:return"老弟,这个算不了" myint=MyInt() res=myint(False) res=myint(45) res=myint(5.99) res=myint(-5.99) res=myint(0.0) #res=myint([3,3,4,5,56]) #res=myint("123") #res=myint("+0000000000000123") res=myint("-00000000000000098addf7") print(res) #print(int("-00000000000000098addf7")) #print(int("+0000000000000123")) #int("sdsdf") #res=eval("00000000123") #print(res,type(res)) #5*1=5 #5*-1=-5 #print(int("000000"))
3.6__str__魔术方法(*)
#__str__魔术方法 '''触发时机:使用print(对象)或者str(对象)的时候触发功能:查看对象参数:一个self接受当前对象返回值:必须返回字符串类型 ''' classCat():gift="九条命,喵喵叫"def__init__(self,name):self.name=namedef__str__(self):returnself.cat_info()defcat_info(self):return"{}小猫天生就有{}".format(self.name,self.gift) tom=Cat("汤姆") #触发方式一print #print(tom) #触发方式二str res=str(tom) print(res)
3.7__repr__魔术方法(*)
#__repr__魔术方法 '''触发时机:使用repr(对象)的时候触发功能:查看对象,与魔术方法__str__相似参数:一个self接受当前对象返回值:必须返回字符串类型 ''' classMouse():gift="打洞"def__init__(self,name):self.name=namedef__repr__(self):returnself.cat_info()defcat_info(self):return"老鼠天赋是{},龙生龙,凤生凤,老鼠的儿子会打洞".format(self.gift)#在底层中,实际上如果存在__repr__,就把他赋值给__str__魔术方法#__str__=__repr__ jerry=Mouse("杰瑞") #res=repr(jerry) #print(res) #print(jerry) res=str(jerry) print(res) #老鼠天赋是打洞,龙生龙,凤生凤,老鼠的儿子会打洞
3.8__bool__魔术方法
#----普通变量的基本操作,如果应用在对象上,也有相应的魔术方法 #__bool__魔术方法 '''触发时机:使用bool(对象)的时候自动触发功能:强转对象参数:一个self接受当前对象返回值:必须是布尔类型 ''' ''' 类似的还有如下等等(了解):__complex__(self)被complex强转对象时调用__int__(self)被int强转对象时调用__float__(self)被float强转对象时调用...... '''
3.9__add__魔术方法
#__add__魔术方法(与之相关的__radd__反向加法) '''触发时机:使用对象进行运算相加的时候自动触发功能:对象运算参数:二个对象参数返回值:运算后的值 ''' ''' 类似的还有如下等等(了解):__sub__(self,other)定义减法的行为:-__mul__(self,other)定义乘法的行为:__truediv__(self,other)定义真除法的行为:/...... '''
3.10__len__魔术方法
#__len__魔术方法 '''触发时机:使用len(对象)的时候自动触发功能:用于检测对象中或者类中某个内容的个数参数:一个self接受当前对象返回值:必须返回整型 ''' ''' 类似的还有如下等等(了解):__iter__(self)定义迭代容器中的元素的行为__reversed__(self)定义当被reversed()调用时的行为__contains__(self,item)定义当使用成员测试运算符(in或notin)时的行为...... '''