一、面向对象基本概念
• 类:用几大特征表述一一类事物。类要表达的是一个抽象的概念。
• 对象:对象是类的具体实现。举个例子,类像是一张图纸,对象是由这张图纸产出的具体物品。类只有一个,但是对象可以同这个类实例出多个。
对象是类的实例,类是对象的模板。
类中的成员只有属性和方法,不要裸露地把判断和循环写在类中,而要用方法包起来。
面向对象的本质就像「搭乐高」:
-
每个积木块都是独立的小机器人(对象)
-
有自己专属的技能(方法)
-
携带自己的工具包(属性)
-
比如「汽车积木」自己会跑、有四个轮子
-
积木之间通过标准接口互相连接
-
不需要知道对方内部怎么运作
-
只要说「帮我运货」,卡车积木就会自动完成任务
-
可以批量生产相似机器人
-
用「机器人模具」(类)造出一模一样的
-
还能给模具加新功能(继承)
-
比如给「动物模具」加翅膀,立刻生成会飞的动物
-
同一个指令能触发不同反应
-
对所有积木喊「干活」,有的扫地、有的做饭(多态)
-
每个积木按自己的方式响应
最终效果:用现实世界的思维方式,把复杂系统拆解成互相协作的智能模块,像指挥机器人战队一样写程序。
1.1类的定义
bash
1
classCar:
2
pass
3
4
#推荐使用下面定义方式
5
classCar():
6
pass
7
8
classCar(object):
9
pass
用AI生成此博客的项目代码

cpp
复制

1.2类的实例化
bash
1
classCar():
2
pass
3
4
#类的实例化,实例化对象,new新对象
5
obj=Car()
用AI生成此博客的项目代码
cpp
复制
1.3类的基本结构
1
#类中只有成员属性和成员方法
2
classCar():
3
#成员属性
4
color="咖啡色"
5
#成员方法
6
defrun():
7
print("fast")
8
用AI生成此博客的项目代码
cpp
复制
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)实例化的对象删除公有成员属性和方法
bash
1
#Part01实例化的对象访问公有成员属性和方法
2
"""
3
4
对象的语法:
5
对象.属性
6
对象.方法()
7
8
绑定方法:
9
(1)绑定到对象(调用方法时候,自动把对象当成参数进行传递)
10
(2)绑定到类(调用方法时候,自动把类当成参数进行传递)
11
"""
12
13
classMyCar():
14
#公有成员属性
15
color="咖啡色"
16
17
#私有成员属性
18
__logo="特斯拉"
19
20
#公有成员方法
21
defrun(self):
22
print("我的小车爬起来很快",self.color)
23
24
#私有成员方法
25
def__info(self):
26
print("我的价格保密,类外不能调用")
27
28
#类的实例化
29
obj=MyCar()
30
31
#对象的相关操作
32
#(1)实例化的对象访问公有成员属性和方法
33
print(obj.color)
34
#obj.__logoerror不能在类外调用私有成员
35
36
"""
37
当对象.方法的时候,系统会自动把前面的对象当成参数进行传递,
38
传递给self这个形参来进行接收,self是约定俗称的名字,代表本对象
39
"""
40
obj.drive()
41
42
#Part02实例化的对象动态添加公有成员属性和方法
43
44
#添加成员属性
45
obj.luntai="米其林"
46
print(obj.luntai)
47
#__dict__查看类或对象的成员结构,返回一个字典
48
print(obj.__dict__)
49
"""
50
color__logodrive__info它们都归属于MyCar这个类的
51
对象可以使用类中的公有成员,但是没有归属权;
52
"""
53
54
#添加成员方法(在类外动态添加方法,默认需要手动传递参数;)
55
#(1)动态添加无参方法
56
defdahuangfeng():
57
print("请叫我大黄蜂,我的车会变形")
58
59
obj.dahuangfeng=dahuangfeng
60
obj.dahuangfeng()
61
62
#(2)动态添加有参方法
63
defqingtianzhu(name):
64
print("请叫我"+name+",我的车会变形")
65
66
obj.qingtianzhu=qingtianzhu
67
obj.qingtianzhu("擎天柱")
68
69
#升级
70
defqingtianzhu(self,name):
71
print("请叫我"+name+",我的车会变形",self.color)
72
#qingtianzhu(obj,"擎天柱")
73
obj.qingtianzhu2=qingtianzhu
74
obj.qingtianzhu2(obj,"擎天柱")
75
76
#利用types改造MethodType(相应的函数,要绑定的对象)
77
importtypes
78
#通过MethodType来创建一个绑定方法,赋值给成员qingtianzhu3
79
obj.qingtianzhu3=types.MethodType(qingtianzhu,obj)
80
#绑定方法意味着在调用时,系统会自动把该对象作为参数进行传递
81
obj.qingtianzhu3("擎天柱3")
82
83
#(3)动态添加lambda匿名函数
84
obj.fadongji=lambda:print("我是制造发动机的方法")
85
obj.fadongji()
86
87
#part03实例化的对象删除公有成员属性和方法
88
#删除属性del对象.属性
89
delobj.oil
90
#print(obj.oil)error
91
#删除方法del类.方法
92
delobj.oil_info
93
#obj.oil_infoerror
用AI生成此博客的项目代码

cpp
复制
展开

1.5.3类的相关操作
(1)定义的类访问公有成员属性和方法
(2)定义的类动态添加公有成员属性和方法
(3)定义的类删除公有成员属性和方法
bash
1
#part01定义的类访问公有成员属性和方法
2
3
classMyCar():
4
#公有成员属性
5
oil="2.0T"
6
#私有成员属性
7
__price="1亿"
8
9
#公有的无参方法
10
defoil_info():
11
print("我的油耗信息",MyCar.__price)
12
#私有的无参方法
13
def__price_info():
14
print("我的价格信息")
15
16
"""
17
#实例化对象
18
obj=MyCar()
19
#对象无法调用无参的公有方法
20
obj.oil_info()
21
"""
22
23
#(1)定义的类访问公有成员属性和方法
24
print(MyCar.oil)
25
#print(MyCar.__price)error无论是对象还是类,都无法在类外调用私有成员;
26
27
MyCar.oil_info()
28
29
#part02定义的类动态添加公有成员属性和方法
30
31
#添加公有成员属性
32
MyCar.logo="宝马"
33
print(MyCar.logo)
34
print(MyCar.__dict__)
35
36
#添加公有成员方法
37
#(1)动态添加公有无参方法
38
deffangxiangpan():
39
print("制造方向盘的方法")
40
MyCar.fangxiangpan=fangxiangpan
41
MyCar.fangxiangpan()
42
43
#(2)动态添加公有的有参方法
44
defcardoor(something):
45
print("我的车门是{}制作的".format(something))
46
47
MyCar.cardoor=cardoor
48
MyCar.cardoor("铝合金")
49
50
#(3)动态添加lambda表达式
51
MyCar.tianchuang=lambdan:print("制造{}的一个方法".format(n))
52
MyCar.tianchuang("天窗")
53
54
55
print(MyCar.__dict__)
56
57
58
"""
59
类中的成员只归属于当前这个类,
60
对象可以调用其中的公有成员,但是没有修改和删除的权利,因为归属于类
61
类无法调用对象中的相关成员,但是对象可以调用类中的相关成员;
62
对象调用成员时,先看看自己有没有该成员,如果有直接调用,如果没有调用类;
63
"""
64
65
#例子
66
obj=MyCar()
67
#obj.fangxiangpan()
68
#对象可以调用类中的公有成员属性方法
69
obj.cardoor()
70
71
#类可以调用对象中的公有成员么?不可以!
72
'''调用对象中的成员时,先看看自己有没有该成员,如果有直接调用,如果没有调用类的;'''
73
#obj.oil="1.5T"
74
#print(obj.oil)
75
#print(MyCar.oil)
76
#obj.oil222="3.0T"
77
#print(MyCar.oil222)
78
79
#part03定义的类删除公有成员属性和方法
80
#删除属性del类.属性
81
delMyCar.oil
82
#print(MyCar.oil)error
83
#删除方法del类.方法
84
delMyCar.oil_info
85
#MyCar.oil_infoerror
用AI生成此博客的项目代码

cpp
复制
展开

1.5.4方法
普通方法:没有任何参数传递,只能类调用
绑定方法:把默认传参的方法叫做绑定方法,绑定到对象(默认传对象),绑定到类(默认传类)
非绑定方法:静态方法(无需传任何参数,对象和类都能调用)
1.5.5类中的私有成员调用方法
(1)利用类调用公有方法调用私有成员(推荐)
(2))利用对象调用公有方法调用私有成员
bash
1
classPlane():
2
#公有成员属性
3
captain="机长"
4
#私有成员属性
5
__airsistant=2
6
7
#公有绑定方法
8
deffly1(self):
9
print("飞的贼快")
10
11
#公有普通无参方法
12
deffly2():
13
print("飞的贼高")
14
15
#私有绑定方法
16
def__plane_info(self):
17
print("飞机上的空姐数量是保密的",self.__airsistant)
18
19
#私有普通方法
20
def__plane_info2():
21
print("飞机上的空姐很好看")
22
23
#用对象调用公有方法(绑定到对象)pub_info间接实现对私有成员的调用
24
defpub_info(self):
25
print(self.__airsistant)
26
self.__plane_info()
27
28
#用类调用公有方法pub_info2间接实现对私有成员的调用(推荐使用!!)
29
defpub_info2():
30
print(Plane.__airsistant)
31
Plane.__plane_info2()
32
33
#实例化对象
34
obj=Plane()
35
#1.类调用
36
Plane.pub_info2()
37
38
#2.对象调用
39
obj.pub_info()
bash

cpp
复制
展开

1.5.6私有成员的命名策略
1
#私有成员的命名策略:_类+私有成员就是该成员的真实名字(不推荐使用)
2
print(obj._Plane__airsistem)
3
#obj._Plane__plane_info()
4
5
print(Plane._Plane__airsistem)
6
#Plane._Plane__plane_info2()
用AI生成此博客的项目代码

cpp
复制

二、面向对象三大特征
(1)封装:对类中成员属性和成员方法的保护,控制外界对内部成员的访问,修改,删除等操作;
(2)继承:一个类除了自身所拥有的属性和方法之外,还获取了另外一个类的属性和方法;
(3)多态:不同的子对象,调用相同的父类方法,产生了不同的执行结果;
2.1封装
参考本文1.5节相关内容。
2.2继承
一个类继承另外一个类,那么该类就是子类(衍生类),被继承的这个类叫做父类(超类,基类)
继承:
(1)单继承(2)多继承
python3中所有的类都默认继承父类object
2.2.1单继承
(1)子父继承之后,子类可以调用父类的公有的属性和方法
(2)子父继承之后,子类不可以调用父类的私有成员
(3)子父继承之后,子类可以改写父类的方法
(4)子父继承之后,子类优先调用自己的成员属性方法,如果没有则调用父类的属性方法,如果都没有,直接报错
bash
1
classHuman():
2
hair="黄色的"
3
__age=18
4
defeat(self):
5
print("人类天生就会吃,吃猎物")
6
7
defla(self):
8
print("人类天生就会上厕所")
9
10
def__makebaby(self):
11
print("人类可以繁衍后代")
12
13
14
15
#(1)子父继承之后,子类可以调用父类的公有的属性和方法
16
classMan(Human):
17
pass
18
19
obj=Man()
20
print(obj.hair)
21
22
#(2)子父继承之后,子类不可以调用父类的私有成员
23
classWoman(Human):
24
defpub_func(self):
25
self.__age
26
self.__makebaby()
27
28
obj=Woman()
29
#obj.__makebaby()error
30
#obj.pub_func()
31
32
33
#(3)子父继承之后,子类可以改写父类的方法
34
"""
35
子父继承之后,
36
如果子类里面有该成员属性方法,优先调用自己的,
37
如果没有该成员属性方法,那么调用父类的属性方法
38
如果都没有,直接报错;
39
"""
40
classChildren(Human):
41
defeat(self):
42
print("小孩天生只会喝奶奶")
43
44
obj=Children()
45
obj.eat()
用AI生成此博客的项目代码

cpp
复制
展开

2.2.2多继承
super的用法:(1)super本身是一个类,super()是一个对象,用于调用父类的绑定方法(2)super()只应用在绑定方法中,默认自动传递self对象(前提:super所在作用域存在self)(3)super用途:解决复杂的多继承调用关系
bash
1
classFather():
2
property="抽烟喝酒"
3
deff_hobby():
4
print("出去喜欢抽烟喝酒")
5
classMother():
6
property="化妆品包包"
7
defm_hobby(self):
8
print("逛街买化妆品包包")
9
10
classSon(Father,Mother):
11
property="打游戏看直播"
12
#1.利用类来调用父类的属性和方法
13
defskill1(self):
14
Father.f_hobby()
15
print(Mother.property)
16
17
#2.利用对象调用父类的属性和方法
18
#self在调用父类方法属性的时候,在本类有的时候,先调用自己的,如果没有,再调用父类的
19
defskill2(self):
20
self.m_hobby()#无,调用父类
21
print(self.property)#有,调用自身
22
23
#3.利用super调用父类的属性和方法
24
#super()只调用父类的相关公有成员,不会调用自己本类中的公有成员,super()特指调用父类,跟self有区别
25
defskill3(self):
26
print(super().property)#多个父类,按顺序继承
27
super().m_hobby()#只应用在绑定方法中
用AI生成此博客的项目代码
cpp
复制
展开
self和super区别
当使用self调用方法时,会从当前类的方法列表中开始找,如果没有,就从父类中再找;而当使用super时,则从父类的方法列表中开始找,然后调用父类的这个方法。
2.2.3菱形继承
多继承的弊端会造成菱形继承这种情况,照不清调用顺序
super对象按照mro列表的顺序依次调用,解决菱形继承存在问题
新式类:广度优先(python3.x)
经典类:深度优先(python2.x)
写多继承时,尽量避免造成不同类相同方法名的情况,提高代码质量,实现"高内聚,低耦合"
高内聚:一个模块只完成一个任务,专一性高
低耦合:模块与模块之间可以彼此独立不冲突,方便移植复用
bash
1
"""
2
Human
3
ManWoman
4
Children
5
"""
6
7
classHuman():
8
pty=444
9
deffeelT(self):
10
print("原始人类天热了,脱光1")
11
print(self.pty)
12
print("原始人类天冷了,烤火2")
13
14
classMan(Human):
15
pty=333
16
deffeelT(self):
17
print("男人天冷了,洗澡3")
18
super().feelT()
19
print("男人天热了,洗澡4")
20
21
classWoman(Human):
22
pty=222
23
deffeelT(self):
24
print("女人天冷了,喝热水5")
25
super().feelT()
26
print("女人天热了,喝冷水6")
27
28
classChildren(Man,Woman):
29
pty=111
30
deffeelT(self):
31
print("小孩天冷了,睡一觉7")
32
super().feelT()
33
print("小孩天热了,睡一觉8")
34
35
obj=Children()
36
obj.feelT()
37
38
"""
39
self.pty打印的值是111,
40
因为在super().feelT的时候,默认传递的对象,是Children实例化出来的对象.最后传到最上层Human这个类当中,进行调用打印111;
41
Children->Man->Woman->Human
42
"""
43
44
#mro列表:语法类.mro()返回的是继承调用关系列表;针对于多继承,解决同名方法的调用顺序;内部用的c3算法;
45
#super()就是按照mro()呈现出来的调用顺序列表,依次的进行调用
46
lst=Children.mro()
47
print(lst)
48
"""
49
[
50
<class'__main__.Children'>,
51
<class'__main__.Man'>,
52
<class'__main__.Woman'>,
53
<class'__main__.Human'>,
54
<class'object'>
55
]
56
"""
57
58
#issubclass判断是否存在子父关系(只要在一个继承链上,有血缘关系即可;)
59
res=issubclass(Children,Man)
60
res=issubclass(Children,Woman)
61
res=issubclass(Children,Human)
62
res=issubclass(Children,(Man,Woman,Human))
63
print(res)
64
65
#isinstance判断是否为实例(只要在一个继承链上,有血缘关系即可;)
66
res=isinstance(obj,Children)
67
res=isinstance(obj,Man)
68
res=isinstance(obj,(Human,Woman))
69
print(res)
用AI生成此博客的项目代码

cpp
复制
展开
issubclass和isinstance对比:
issubclass:判断两个类是否是同类或者在同一继承链上
isinstance:判断一个实例是否为一个类或该子类的实例
相同点:都能判断是否有继承关系
不相同:insubclass用于判断两个类的继承关系,而isinstance用于判断实例化
2.3多态
概念:不同的子类对象,调用相同的父类方法,产生了不同的执行效果
关键字:继承,改写
多态作用:在不改写父类代码的前提下,能实现不同的效果
bash
1
classSoldier():
2
#攻击
3
defattack(self):
4
pass
5
#撤退
6
defback(self):
7
pass
8
9
#陆军
10
classArmy(Soldier):
11
defattack(self):
12
print("[陆军]上来拼刺刀,你捅我我捅你,一刀999级")
13
14
defback(self):
15
print("[陆军]撒腿就跑")
16
17
#海军
18
classNavy(Soldier):
19
defattack(self):
20
print("[海军]上来就扔鱼叉子,插死一个算一个")
21
22
defback(self):
23
print("[海军]直接跳海,下海喂鱼")
24
25
#空军
26
classAirForce(Soldier):
27
defattack(self):
28
print("[空军]打飞机,用二营长的意大利跑射击")
29
30
defback(self):
31
print("[空军]原地跳伞,落地成盒")
32
33
#实例化陆军,产生士兵对象
34
obj_army=Army()
35
36
#实例化海军,产生士兵对象
37
obj_navy=Navy()
38
39
#实例化空军,产生士兵对象
40
obj_airforce=AirForce()
41
42
43
#各就位准备针对于对象;
44
lst=[obj_army,obj_navy,obj_airforce]
45
46
#让将军下令指挥
47
"""
48
1.全体出击
49
2.全体撤退
50
3.空军上,其他人迅速撤离
51
4.按4退出
52
"""
53
54
sign=True
55
whilesign:
56
num=int(input("将军请下令:"))
57
foriinlst:
58
ifnum==1:
59
i.attack()
60
elifnum==2:
61
i.back()
62
elifnum==3:
63
#isinstance判断对象的类型
64
ifisinstance(i,AirForce):
65
i.attack()
66
else:
67
i.back()
68
elifnum=="4":
69
print("谢谢将军的指挥,您辛苦了")
70
sign=False
71
break
72
else:
73
print("报告:风太大,没听清楚,麻烦再说一遍!")
74
break
用AI生成此博客的项目代码

cpp
复制
展开

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

3.1__init__魔术方法
1
#__init__魔术方法(构造方法)
2
'''
3
触发时机:实例化对象,初始化的时候触发
4
功能:为对象添加成员
5
参数:参数不固定,至少一个self参数
6
返回值:无
7
8
'''
9
classChildren():
10
def__init__(self,name,skin):
11
self.name=name
12
self.skin=skin
13
14
defcry(self):
15
print("小孩下生就哭")
16
17
defdrink(self):
18
print("小孩一下生就喜欢喝奶奶")
19
20
def__baobao(self):
21
print("小孩下生要抱抱~")
22
23
defpub_func(self):
24
self.__baobao()
25
26
defobj_info(self):
27
print("该对象的名字是{},该对象的肤色是{}".format(self.name,self.skin))
28
29
obj=Children("王钢蛋","黑色")
30
31
obj.cry()
32
obj.obj_info()
bash

cpp
复制
展开

3.2__new__魔术方法
1
#__new__魔术方法
2
'''
3
触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
4
功能:控制对象的创建过程
5
参数:至少一个cls接受当前的类,其他根据情况决定
6
返回值:通常返回对象或None
7
'''
8
#(1)基本语法
9
classMyClass():
10
a=1
11
obj_other=MyClass()
12
13
classMyClass1():
14
def__new__(cls):
15
print(cls)#MyClass1
16
#借助父类object里面__new__魔术方法,把对应的参数类传递进来,就会对应为当前这个类创建对象
17
#obj=object.__new__(cls)
18
#不返回任何对象,None
19
#返回自己本类对象
20
#returnobj
21
#返回其他类对象
22
returnobj_other
23
24
obj=MyClass1()
25
print(obj)#<__main__.MyClassobjectat0x000002911AB679E8>
26
27
#(2)__new__和__init__方法对比
28
"""
29
__new__用来创建对象
30
__init__用来初始化对象
31
32
先创建对象,再初始化对象,所以__new__要快于__init__
33
__new__和__init参数个数要一一对应
34
"""
35
36
#一个参数
37
classBoat():
38
def__new__(cls,name):
39
returnobject.__new__(cls)
40
41
def__init__(self,name):
42
print(name)
43
obj=Boat("吴彦祖")#吴彦祖
44
45
#多个参数
46
classBoat():
47
def__new__(cls,*args,**kwargs):
48
returnobject.__new__(cls)
49
50
def__init__(self,*args,**kwargs):
51
print(args)
52
print(kwargs)
53
obj=Boat("吴彦祖",1,2,name="吴彦祖")
54
#('吴彦祖',1,2)
55
#{'name':'吴彦祖'}
56
57
58
#注意点:如果返回的不是自己本类对象,那么不会触发__init__构造方法
59
classBoat():
60
def__new__(cls,*args,**kwargs):
61
returnobj_other
62
#returnNone
63
64
def__init__(self):
65
print("构造方法被触发")
66
obj=Boat()
67
#无任何输出
用AI生成此博客的项目代码

cpp
复制
展开

3.3单态(例)模式
单态(例)模式:无论实例化多少次,都有且只有一个对象;
目的:为了节省内存空间,仅仅是单纯利用对象调用相关成员,不需要动态添加属性方法,用单态模式即可;
bash
1
#(1)基本语法
2
#经典单例模式代码,必须掌握!!!
3
classSingleton():
4
__obj=None
5
def__new__(cls):
6
ifcls.__obj==None:
7
cls.__obj==object.__new__(cls)
8
returncls.__obj
9
10
"""
11
第一次在进行实例化的时候cls.__objisNone为真,所以执行代码块;通过父类创建好对象,赋值给cls.__obj
12
returncls.__obj
13
14
第二次进行实例化的时候cls.__objisNone为假,不执行对应代码块,直接returncls.__obj
15
16
第三次进行实例化的时候cls.__objisNone为假,不执行对应代码块,直接returncls.__obj
17
18
把obj变成私有成员为了防止用户在类外直接调用该成员,形成一种保护;
19
"""
20
obj1=Singleton()
21
obj2=Singleton()
22
obj3=Singleton()
23
print(obj1isobj2)#True
24
print(obj1,obj2,obj3)#id相同
25
26
#(2)单例模式+__init__
27
```python
28
classSingleton():
29
__obj=None
30
def__new__(cls,*args,**kwags):
31
ifcls.__objisNone:
32
cls.__obj=object.__new__(cls)
33
returncls.__obj
34
35
def__init__(self,name):
36
self.name=name
37
obj1=Singleton("赵丽颖")
38
obj2=Singleton("杨幂")
39
40
#无论实例多少次都是同一个对象
41
print(obj1.name)#杨幂
42
print(obj2.name)#杨幂
bash

cpp
复制
展开

3.4__del__魔术方法
1
#__del__魔术方法(析构方法)
2
'''
3
触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量2.所有对象被del的时候]
4
功能:对象使用完毕后资源回收
5
参数:一个self接受对象
6
返回值:无
7
'''
8
9
classLangDog():
10
food="吃肉"
11
def__init__(self,name):
12
self.name=name
13
def__del__(self):
14
print("析构方法被触发了..")
15
16
#(1)页面执行完毕回收所有变量
17
obj=LangDog("辛巴")
18
print(obj.name)
19
20
#(2)所有对象被del的时候
21
obj2=obj
22
print(objisobj2)
23
24
print("<==start==>")
25
delobj
26
delobj2
27
print("<==end==>")
28
29
30
31
#用析构方法模拟文件读取操作
32
"""
33
fp=open("ceshi.txt",mode="w",encoding="utf-8")
34
fp.write("112344")
35
fp.close()
36
37
fp=open("ceshi.txt",mode="r",encoding="utf-8")
38
res=fp.read()
39
print(res)
40
fp.close()
41
"""
42
importos
43
classReadFile(object):
44
def__new__(cls,filename):
45
#创建ReadFile的对象
46
#判断文件是否存在
47
ifos.path.exists(filename):
48
returnobject.__new__(cls)
49
else:
50
returnprint("该文件不存在")
51
52
def__init__(self,filename):
53
#打开文件操作
54
self.fp=open(filename,mode="r",encoding="utf-8")
55
56
defreadcontent(self):
57
#读取文件操作
58
content=self.fp.read()
59
returncontent
60
61
def__del__(self):
62
#关闭文件操作
63
self.fp.close()
64
65
#存在这个文件的时候,可以调用readcontent
66
obj=ReadFile("ceshi.txt")
67
print(obj)
68
res=obj.readcontent()
69
print(res)
70
71
#不存在这个文件的时候,直接报错;
72
obj=ReadFile("ceshisadfsadf'.txt")
73
print(obj)
74
obj.readcontent()
bash

cpp
复制
展开

3.5__call__魔术方法
1
#__call__魔术方法
2
'''
3
触发时机:把对象当作函数调用的时候自动触发
4
功能:模拟函数化操作
5
参数:参数不固定,至少一个self参数
6
返回值:看需求
7
'''
8
#(1)基本用法
9
classMyClass():
10
def__call__(self):
11
print("call魔术方法被触发")
12
13
obj=MyClass()
14
obj()#call魔术方法被触发
15
16
#(2)模拟洗衣服的过程
17
classWash():
18
#用call魔术方法做统一的调用
19
def__call__(self,something):
20
self.step1(something)
21
self.step2(something)
22
self.step3()
23
24
defstep1(self,something):
25
print("把{}泡在盆里面".format(something))
26
27
defstep2(self,something):
28
print("弄点蓝月亮,吊牌,汰渍泡在{}中搓一搓".format(something))
29
30
defstep3(self):
31
print("扭干净,晒一下,穿上")
32
33
obj=Wash()
34
obj("裤衩")
35
'''
36
把裤衩泡在盆里面
37
弄点蓝月亮,吊牌,汰渍泡在裤衩中搓一搓
38
扭干净,晒一下,穿上
39
'''
40
41
#(3)模拟内置方法int实现myint
42
#int("345")345"234"3.14TrueFalse
43
#boolintfloatstr
44
importmath
45
classMyInt():
46
47
#计算最终的结果
48
defmycalc(self,num,sign=1):
49
#去掉左边所有多余的0
50
strvar=num.lstrip("0")
51
#如果传递的是"0000"就强制给它0
52
ifstrvar=="":
53
return0
54
#计算最终的数字结果
55
returneval(strvar)*sign
56
57
def__call__(self,num):
58
ifisinstance(num,bool):
59
ifnum==False:
60
return0
61
else:
62
return1
63
64
elifisinstance(num,int):
65
returnnum
66
67
elifisinstance(num,float):
68
ifnum>0:
69
returnmath.floor(num)
70
else:
71
returnmath.ceil(num)
72
73
elifisinstance(num,str):
74
if(num[0]=="+"ornum[0]=="-")andnum[1:].isdecimal():
75
#sign用来控制正负号
76
ifnum[0]=="+":
77
sign=1
78
else:
79
sign=-1
80
#计算结果
81
returnself.mycalc(num[1:],sign)
82
elifnum.isdecimal():
83
returnself.mycalc(num)
84
else:
85
return"老弟,这个也算不了"
86
87
else:
88
return"老弟,这个算不了"
89
90
91
myint=MyInt()
92
res=myint(False)
93
res=myint(45)
94
res=myint(5.99)
95
res=myint(-5.99)
96
res=myint(0.0)
97
#res=myint([3,3,4,5,56])
98
#res=myint("123")
99
#res=myint("+0000000000000123")
100
res=myint("-00000000000000098addf7")
101
print(res)
102
103
#print(int("-00000000000000098addf7"))
104
#print(int("+0000000000000123"))
105
#int("sdsdf")
106
#res=eval("00000000123")
107
#print(res,type(res))
108
109
#5*1=5
110
#5*-1=-5
111
112
#print(int("000000"))
bash

cpp
复制
展开

3.6__str__魔术方法
1
#__str__魔术方法
2
'''
3
触发时机:使用print(对象)或者str(对象)的时候触发
4
功能:查看对象
5
参数:一个self接受当前对象
6
返回值:必须返回字符串类型
7
'''
8
classCat():
9
gift="九条命,喵喵叫"
10
11
def__init__(self,name):
12
self.name=name
13
14
def__str__(self):
15
returnself.cat_info()
16
17
defcat_info(self):
18
return"{}小猫天生就有{}".format(self.name,self.gift)
19
20
tom=Cat("汤姆")
21
#触发方式一print
22
#print(tom)
23
#触发方式二str
24
res=str(tom)
25
print(res)
26
bash

cpp
复制
展开

3.7__repr__魔术方法
1
#__repr__魔术方法
2
'''
3
触发时机:使用repr(对象)的时候触发
4
功能:查看对象,与魔术方法__str__相似
5
参数:一个self接受当前对象
6
返回值:必须返回字符串类型
7
'''
8
classMouse():
9
gift="打洞"
10
11
def__init__(self,name):
12
self.name=name
13
14
def__repr__(self):
15
returnself.cat_info()
16
17
defcat_info(self):
18
return"老鼠天赋是{},龙生龙,凤生凤,老鼠的儿子会打洞".format(self.gift)
19
20
#在底层中,实际上如果存在__repr__,就把他赋值给__str__魔术方法
21
#__str__=__repr__
22
23
jerry=Mouse("杰瑞")
24
#res=repr(jerry)
25
#print(res)
26
27
28
#print(jerry)
29
res=str(jerry)
30
print(res)
31
#老鼠天赋是打洞,龙生龙,凤生凤,老鼠的儿子会打洞
bash

cpp
复制
展开

3.8__bool__魔术方法
1
#----普通变量的基本操作,如果应用在对象上,也有相应的魔术方法
2
3
#__bool__魔术方法
4
'''
5
触发时机:使用bool(对象)的时候自动触发
6
功能:强转对象
7
参数:一个self接受当前对象
8
返回值:必须是布尔类型
9
'''
10
'''
11
类似的还有如下等等(了解):
12
__complex__(self)被complex强转对象时调用
13
__int__(self)被int强转对象时调用
14
__float__(self)被float强转对象时调用
15
...
16
...
17
'''
bash

cpp
复制
展开

3.9__add__魔术方法
1
#__add__魔术方法(与之相关的__radd__反向加法)
2
'''
3
触发时机:使用对象进行运算相加的时候自动触发
4
功能:对象运算
5
参数:二个对象参数
6
返回值:运算后的值
7
'''
8
'''
9
类似的还有如下等等(了解):
10
__sub__(self,other)定义减法的行为:-
11
__mul__(self,other)定义乘法的行为:
12
__truediv__(self,other)定义真除法的行为:/
13
...
14
...
15
'''
bash

cpp
复制
展开

3.10__len__魔术方法
1
#__len__魔术方法
2
'''
3
触发时机:使用len(对象)的时候自动触发
4
功能:用于检测对象中或者类中某个内容的个数
5
参数:一个self接受当前对象
6
返回值:必须返回整型
7
'''
8
'''
9
类似的还有如下等等(了解):
10
__iter__(self)定义迭代容器中的元素的行为
11
__reversed__(self)定义当被reversed()调用时的行为
12
__contains__(self,item)定义当使用成员测试运算符(in或notin)时的行为
13
...
14
...
15
'''
用AI生成此博客的项目代码

cpp
复制
展开
v