5、Python3编程之面向对象

一、面向对象基本概念
  • 类:用几大特征表述一一类事物。类要表达的是一个抽象的概念。

  • 对象:对象是类的具体实现。举个例子,类像是一张图纸,对象是由这张图纸产出的具体物品。类只有一个,但是对象可以同这个类实例出多个。

对象是类的实例,类是对象的模板。

类中的成员只有属性和方法,不要裸露地把判断和循环写在类中,而要用方法包起来。

面向对象的本质就像「搭乐高」:

  1. 每个积木块都是独立的小机器人(对象)

    • 有自己专属的技能(方法)

    • 携带自己的工具包(属性)

    • 比如「汽车积木」自己会跑、有四个轮子

  2. 积木之间通过标准接口互相连接

    • 不需要知道对方内部怎么运作

    • 只要说「帮我运货」,卡车积木就会自动完成任务

  3. 可以批量生产相似机器人

    • 用「机器人模具」(类)造出一模一样的

    • 还能给模具加新功能(继承)

    • 比如给「动物模具」加翅膀,立刻生成会飞的动物

  4. 同一个指令能触发不同反应

    • 对所有积木喊「干活」,有的扫地、有的做饭(多态)

    • 每个积木按自己的方式响应

最终效果:用现实世界的思维方式,把复杂系统拆解成互相协作的智能模块,像指挥机器人战队一样写程序。

1.1类的定义
复制代码
classCar:
    pass
    
#推荐使用下面定义方式
classCar():
    pass
​
classCar(object):
    pass
1.2类的实例化
复制代码
classCar():
    pass
​
#类的实例化,实例化对象,new新对象
obj=Car()
1.3类的基本结构
复制代码
#类中只有成员属性和成员方法
classCar():
    #成员属性
    color="咖啡色"
    #成员方法
    defrun():
        print("fast")
​
1.4类的命名

类的命名推荐使用驼峰命名法,如:

MyCar,MaHuaTeng;

1.5对象、类的相关操作
1.5.1成员等级

python对成员的保护分为两个等级:

  1. 私有的(private):在本类内部可以访问,类的外部不可以访问 。(python中属性或者方法前面加两个下划线"_"

  2. 公有的(public):在本类的内部和外部都可以访问

  3. 受保护的(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)动态添加无参方法
defdahuangfeng():
    print("请叫我大黄蜂,我的车会变形")
​
obj.dahuangfeng=dahuangfeng
obj.dahuangfeng()
​
#(2)动态添加有参方法
defqingtianzhu(name):
    print("请叫我"+name+",我的车会变形")
​
obj.qingtianzhu=qingtianzhu
obj.qingtianzhu("擎天柱")
​
#升级
defqingtianzhu(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)动态添加公有无参方法
deffangxiangpan():
    print("制造方向盘的方法")
MyCar.fangxiangpan=fangxiangpan
MyCar.fangxiangpan()
​
#(2)动态添加公有的有参方法
defcardoor(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))利用对象调用公有方法调用私有成员
复制代码
classPlane():
    #公有成员属性
    captain="机长"
    #私有成员属性
    __airsistant=2
​
#公有绑定方法
deffly1(self):
    print("飞的贼快")
​
#公有普通无参方法
deffly2():
    print("飞的贼高")
​
#私有绑定方法
def__plane_info(self):
    print("飞机上的空姐数量是保密的",self.__airsistant)
​
#私有普通方法
def__plane_info2():
    print("飞机上的空姐很好看")
​
#用对象调用公有方法(绑定到对象)pub_info间接实现对私有成员的调用
defpub_info(self):
    print(self.__airsistant)
    self.__plane_info()
​
#用类调用公有方法pub_info2间接实现对私有成员的调用(推荐使用!!)
defpub_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)子父继承之后,子类优先调用自己的成员属性方法,如果没有则调用父类的属性方法,如果都没有,直接报错

复制代码
classHuman():
    hair="黄色的"
    __age=18
    defeat(self):
        print("人类天生就会吃,吃猎物")
    
    defla(self):
        print("人类天生就会上厕所")
    
    def__makebaby(self):
        print("人类可以繁衍后代")
    
​
​
#(1)子父继承之后,子类可以调用父类的公有的属性和方法
classMan(Human):
    pass
​
obj=Man()
print(obj.hair)
​
#(2)子父继承之后,子类不可以调用父类的私有成员
classWoman(Human):
    defpub_func(self):  
        self.__age
        self.__makebaby()
        
obj=Woman()
#obj.__makebaby()error
#obj.pub_func()
​
​
#(3)子父继承之后,子类可以改写父类的方法
"""
子父继承之后,
如果子类里面有该成员属性方法,优先调用自己的,
如果没有该成员属性方法,那么调用父类的属性方法
如果都没有,直接报错;
"""
classChildren(Human):
    defeat(self):
        print("小孩天生只会喝奶奶")
        
obj=Children()
obj.eat()
2.2.2多继承

super的用法:(1)super本身是一个类,super()是一个对象,用于调用父类的绑定方法(2)super()只应用在绑定方法中,默认自动传递self对象(前提:super所在作用域存在self)(3)super用途:解决复杂的多继承调用关系

复制代码
classFather():
    property="抽烟喝酒"
    deff_hobby():
        print("出去喜欢抽烟喝酒")
classMother():
    property="化妆品包包"
    defm_hobby(self):
        print("逛街买化妆品包包")
​
classSon(Father,Mother):
    property="打游戏看直播"
    #1.利用类来调用父类的属性和方法
    defskill1(self):
        Father.f_hobby()
        print(Mother.property)
​
    #2.利用对象调用父类的属性和方法
    #self在调用父类方法属性的时候,在本类有的时候,先调用自己的,如果没有,再调用父类的
    defskill2(self):
        self.m_hobby()#无,调用父类
        print(self.property)#有,调用自身
    
    #3.利用super调用父类的属性和方法
    #super()只调用父类的相关公有成员,不会调用自己本类中的公有成员,super()特指调用父类,跟self有区别
    defskill3(self):
        print(super().property)#多个父类,按顺序继承
        super().m_hobby()#只应用在绑定方法中

self和super区别(****)

当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用super时,则从父类的方法列表中开始找,然后调用父类的这个方法。

2.2.3菱形继承

多继承的弊端会造成菱形继承这种情况,照不清调用顺序

super对象按照mro列表的顺序依次调用,解决菱形继承存在问题

新式类:广度优先(python3.x)

经典类:深度优先(python2.x)

写多继承时,尽量避免造成不同类相同方法名的情况,提高代码质量,实现"高内聚,低耦合"

高内聚:一个模块只完成一个任务,专一性高

低耦合:模块与模块之间可以彼此独立不冲突,方便移植复用

复制代码
"""
Human
ManWoman
Children
"""
​
classHuman():
    pty=444
    deffeelT(self):
        print("原始人类天热了,脱光1")
        print(self.pty)
        print("原始人类天冷了,烤火2")
        
classMan(Human):
    pty=333
    deffeelT(self):
        print("男人天冷了,洗澡3")
        super().feelT()
        print("男人天热了,洗澡4")
        
classWoman(Human):
    pty=222
    deffeelT(self):
        print("女人天冷了,喝热水5")
        super().feelT()
        print("女人天热了,喝冷水6")
    
classChildren(Man,Woman):
    pty=111
    deffeelT(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多态

概念:不同的子类对象,调用相同的父类方法,产生了不同的执行效果

关键字:继承改写

多态作用:在不改写父类代码的前提下,能实现不同的效果

复制代码
classSoldier():
    #攻击
    defattack(self):
        pass
    #撤退
    defback(self):
        pass
​
#陆军
classArmy(Soldier): 
    defattack(self):
        print("[陆军]上来拼刺刀,你捅我我捅你,一刀999级")
        
    defback(self):
        print("[陆军]撒腿就跑")
​
#海军
classNavy(Soldier):
    defattack(self):
        print("[海军]上来就扔鱼叉子,插死一个算一个")
        
    defback(self):
        print("[海军]直接跳海,下海喂鱼")
        
#空军
classAirForce(Soldier):
    defattack(self):
        print("[空军]打飞机,用二营长的意大利跑射击")
​
    defback(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=False
            break
        else:
            print("报告:风太大,没听清楚,麻烦再说一遍!")
            break   
三、魔术方法

魔术方法:特定时机自动触发

3.1__init__魔术方法(****)
复制代码
#__init__魔术方法(构造方法)
'''
    触发时机:实例化对象,初始化的时候触发
    功能:为对象添加成员
    参数:参数不固定,至少一个self参数
    返回值:无
​
'''
classChildren():
    def__init__(self,name,skin):
        self.name=name
        self.skin=skin
        
    defcry(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=None
    def__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=None
    def__new__(cls,*args,**kwags):  
        ifcls.__objisNone:
            cls.__obj=object.__new__(cls)       
        returncls.__obj
        
    def__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=name
    def__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()
        returncontent
        
    def__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):
        #去掉左边所有多余的0
        strvar=num.lstrip("0")
        #如果传递的是"0000"就强制给它0
        ifstrvar=="":
            return0
        #计算最终的数字结果
        returneval(strvar)*sign
        
    def__call__(self,num):
        ifisinstance(num,bool):
            ifnum==False:
                return0
            else:
                return1
        
        elifisinstance(num,int):
            returnnum
            
        elifisinstance(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=1
                else:
                    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=name
    
    def__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=name
        
    def__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)时的行为

...

...

'''

相关推荐
星光一影几秒前
教育培训机构消课管理系统智慧校园艺术舞蹈美术艺术培训班扣课时教务管理系统
java·spring boot·mysql·vue·mybatis·uniapp
lkbhua莱克瓦243 分钟前
MySQL介绍
java·开发语言·数据库·笔记·mysql
武昌库里写JAVA6 分钟前
在iview中使用upload组件上传文件之前先做其他的处理
java·vue.js·spring boot·后端·sql
董世昌419 分钟前
什么是事件冒泡?如何阻止事件冒泡和浏览器默认事件?
java·前端
好度16 分钟前
配置java标准环境?(详细教程)
java·开发语言
teacher伟大光荣且正确21 分钟前
关于Qt QReadWriteLock(读写锁) 以及 QSettings 使用的问题
java·数据库·qt
nightseventhunit23 分钟前
base64字符串String.getByte导致OOM Requested array size exceeds VM limit
java·oom
钱彬 (Qian Bin)31 分钟前
项目实践13—全球证件智能识别系统(内网离线部署大模型并调用)
数据库·postgresql·fastapi·ubuntu24.04·离线部署·qwen3大模型
hgz071032 分钟前
索引的原理
数据库
悟能不能悟39 分钟前
java map判断是否有key,get(key)+x,否则put(key,x)的新写法
java·开发语言