五、Python基础(类与对象)
目录:
- 五、Python基础(类与对象)
-
-
-
- 一、面向对象(OOP)
- 二、类与对象
-
- 1.类的基本概念
- 2.对象的基本概念
- 3.类的设计
- 三、面向对象基础语法
-
- 1.dir内置函数
-
- \_\_方法名__
- dir(对象名)
-
-
-
- 2.定义简单的类(只包含方法)和创建对象
-
-
- 对象变量 = 类名()
- 对象.方法名(self, 参数列表)
-
-
-
- 3.方法中的self参数
-
-
- print(对象名)
-
-
-
- 4.初始化方法
-
-
- self.属性 = 属性值
- self.属性
- 对象.属性
-
-
-
- 5. \_\_del__ 方法
- 6. \_\_str__ 方法
- 7.阶段小结(一):简单的三国杀
- 8.阶段小结(二):士兵突击
- 9.补充:身份运算符
- 10.补充:私有属性和私有方法
-
-
- self.\_\_属性 = 属性值
- def \_\_方法(self...):
-
-
- 上一篇文章
- 下一篇文章
-
-
一、面向对象(OOP) 面向对象的基本概念
(1)面向过程
- 把实现一个需求的全部步骤从头到尾地完整实现
- 比面向对象更为复杂,涉及到更复杂的算法设计和语法
- C语言是典型的面向过程语言
- 在完成一个需求前,首先确定职责——要做的事情(方法)
- 根据职责确定不同的对象,在对象中封装不同的方法(多个)
- 最后的代码,就是顺序地让不同的对象调用不同的方法
- 相比较函数,面向对象是更大的封装
- 特征被称为属性
- 行为被称为方法
2.对象的基本概念 对象是由类创建出来的一个具体存在,可以直接使用,由哪一个类创建出来的对象,就拥有在哪一个类中定义的属性和方法,对象就相当于用图纸(类)制造飞机
- 在程序的开发中,应该先有类,然后有对象
在程序开发中,要设计一个类,通常需要满足以下三要素:
- 类名 这类事物的名字,应满足大驼峰命名法
- 属性 这类事物应该具有怎么样的特征
- 方法 这类事物应该具有怎么样的行为
- 对对象的特征描述,通常可以定义成属性
- 对象具有的行为(动词),通常可以定义为 __方法__
__方法名__ 所有以这种前后两个下划线格式命名的方法是Python提供的内置方法/属性注:由于方法较多,若直接 print(dir()) 调用直接列表的方式列出,可能会导致横向输出过长
dir(对象名) 可以列出该对象中可以使用的所有属性及方法,它是以字符串列表的方式列出(横向)
例:
list_name = [1, 2, 3]"""直接横向输出看看效果"""
print(dir(list_name))i = 1
for method in dir(list_name):
"""每列出5个方法进行一次换行"""
if i % 5 == 0:
print()print(method, end="")
i += 1
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202I631-0.jpg)
文章图片
在上述内置的方法中,有一些较为常用的:
序号 | 方法名 | 类型 | 作用 |
---|---|---|---|
1 | __new__ | 方法 | 创建对象时,会被自动调用 |
2 | __init__ | 方法 | 对象初始化时,会被自动调用 |
3 | __del__ | 方法 | 对象被从内存中销毁前,会被自动调用 |
4 | __str__ | 方法 | 返回对象的描述信息,print函数输出使用 |
5 | __doc__ | 方法 | 查看函数/类中的方法的解释文档 |
def function(temp_num):
"""
这是函数的解释文档:param temp_num: 函数的参数
:return: 没有返回值
"""
print(temp_num)print(function.__doc__)
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202L163-1.png)
文章图片
2.定义简单的类(只包含方法)和创建对象 面向对象是相较于函数而言更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了
(1)定义简单的类的方法:
定义类的简单方法的结构示意图:
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202J5W-2.png)
文章图片
- 类名应当满足大驼峰命名法
对象变量 = 类名() 即可为某个指定的类创建一个方法(3)对象调用类中的方法:
对象.方法名(self, 参数列表) 调用类中的方法,这个类似于高级变量类型调用方法的语法例:创建一个 PersonJob 职业类,根据这个类定义一个职业 driver,即可调用类中的方法
注:self 不传递参数
——这里暂时没有提到self,后面会说到
class PersonJob:
"""在类中定义多个方法"""
def function1(self):
print("工作内容")def function2(self):
print("工作薪资")driver = PersonJob()driver.function1()
driver.function2()
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202I232-3.png)
文章图片
注:在面向对象开发中,我们在 四、Python基础(变量进阶)中提到的引用的概念是同样适用的
3.方法中的self参数 实际上,self 保存的是对象的引用,即哪一个对象调用了类中的方法,self 就是哪一个对象的引用,它可以通过属性名来访问对象的属性
print(对象名) 即可查看指定对象所属的类和所引用的地址(十六进制)4.初始化方法 当使用类名创建对象时,会自动执行以下操作:
![]()
文章图片
- 为对象在内存中分配空间——创建对象
- 为对象的属性设置初始值——初始化方法(__init__),这个初始化方法就是 __init__ 方法,__init__ 方法是对象的内置方法
- __init__ 方法是专门用来定义一个类中具有哪些属性的方法,而基于这个类定义的对象都将具有这些属性,不同对象有共同的属性,但属性值可以不同,如:名字是人们的共同属性,但名字可以不同(属性值可以不同)(重要)
self.属性 = 属性值 可以在类的方法内部定义对象的属性
注:这个方法还可以在类的外部进行属性的定义,但不推荐在外部使用:
提示:当暂时不知道设置什么属性值时,可以写 self.属性 = None 表示空值
- 首先是因为在外部定义会降低代码的可读性
- 其次,在外部定义时,在定义前的代码是不能访问到该属性的,会造成错乱
self.属性 在类的内部的方法可以通过这个方式来访问到类的属性(对象的属性)
对象.属性 在类的外部可以通过这个方法来访问到对象的属性
- 属性是共有的,对不同对象而言,同一属性下的属性值是可以不同的(重要)
"""职业类"""
class PersonJob:
def __init__(self, object_name):
"""属性名:必要性"""
self.necessity = "重要的"
"""属性名:种类"""
self.kind = "多样的"
"""属性名:名字(可以不同)"""
self.name = object_namedef function1(self):
print("PersonJob的necessity属性是:%s" % self.necessity)
print("PersonJob的kind属性是:%s" % self.kind)
print("PersonJob中,driver这个对象的name属性是:%s" % self.name)"""driver属于PersonJob类,因此它具有这个类中的属性名"""
driver = PersonJob("司机")driver.function1()
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202L358-5.png)
文章图片
创建类的完整结构示意图:
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202K1O-6.jpg)
文章图片
补充:
- 基于类创建的对象通常也称为类的实例
- 创建对象的过程通常也称为实例化
- 对象的属性通常也称为实例属性
- 对象调用的方法通常也称为实例方法
- 类似于 C++ 或 PHP 等语言的析构函数
- 我们知道,__init__ 是在对象被初始化时自动调用的方法,目的是创建对象的属性
- 那么与 __init__ 相反的是 __del__ ,它是在对象的内存被释放时自动调用的方法,目的是在对象的内存被释放前执行最后一项工作
- 主动调用 “ del 对象 ”,即可让对象执行 __del__ ,然后释放内存
- 程序执行结束前,所有的内存都被释放,此时在对象的内存被释放前, __del__ 将会被自动调用
- 因此,凡是定义了 __del__ 方法的,它终会被执行
"""职业类"""
class PersonJob:
def __init__(self, object_name):
"""属性名:必要性"""
self.necessity = "重要的"
"""属性名:种类"""
self.kind = "多样的"
"""属性名:名字"""
self.name = object_namedef __del__(self):
print("对象的内存被释放前将自动调用")job1 = PersonJob("job1")
job2 = PersonJob("job2")del job1
print("-" * 10)
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202M613-7.png)
文章图片
6. __str__ 方法 前面提到过,用 print(对象) 的默认输出格式是:输出这个对象是由哪一个类创建的,以及其在内存中引用的地址(十六进制)
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202J150-8.jpg)
文章图片
如果在开发中,希望使用 print 输出对象变量时,能够打印自定义的内容,就可以利用 __str__ 这个内置方法来设定了,即自定义修改print的默认输出格式
注: __str__ 这个方法,必须要返回一个字符串
例:
class PersonJob:
def __init__(self, object_name):
# 属性名:必要性
self.necessity = "重要的"
# 属性名:种类
self.kind = "多样的"
# 属性名:名字
self.name = object_namedef __str__(self):
return "这里是print(对象)将会打印的内容,可以使用属性,如:%s" % self.namedriver = PersonJob("司机")
print(driver)
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202J131-9.png)
文章图片
提示:如果有多个类,则被使用的类应该先被创建
7.阶段小结(一):简单的三国杀 需求:
(1)定义一个武将类,它包括:
- 属性——武将名、生命值、攻击力
- 打印:输出武将的当前属性
- 吃桃:生命值+1
- 装备武器:武器名、武器增加攻击力数值
- 攻击:攻击目标、目标生命值–=攻击方攻击力
- 胜利提示,阵亡提示
- 游戏过程:
- 打印双方武将属性
- 吕布装备方天画戟,攻击力+4
- 赵云吃桃,生命值+1
- 吕布对赵云发动攻击,赵云阵亡
- 吕布获胜
class MilitaryOfficer:
"""定义一个武将类"""
def __init__(self, name, hp):
"""武将名"""
self.name = name
"""武将生命值"""
self.hp = hp
"""武将初始攻击力均为1"""
self.attack = 1
print(self)"""打印武将当前战斗状态"""
def __str__(self):
return "[武将]:%s,攻击力:%d,当前生命值:%d" % (self.name, self.attack, self.hp)"""吃桃,生命值加1"""
def eat(self):
print("%s吃了一个桃,HP+1" % self.name)
self.hp += 1
print(self)"""装备武器"""
def equip(self, name, value):
print("%s装备了%s,攻击力+%d" % (self.name, name, value))
self.attack += value
print(self)"""攻击,根据攻击力造成伤害"""
def fight(self, target):
target.hp -= self.attack
print("%s对%s发动了攻击,造成了%d点伤害" % (self.name, target.name, self.attack))
if target.hp <= 0:
print("%s已阵亡,当前生命值:%d" % (target.name, target.hp))else:
print(target)"""游戏结束时提示胜利方"""
def __del__(self):
if self.hp > 0:
print("%s获得了胜利" % self.name)else:
pass"""分别定义两个武将"""
lvbu = MilitaryOfficer("吕布", 4)
zhaoyun = MilitaryOfficer("赵云", 4)lvbu.equip("方天画戟", 4)
zhaoyun.eat()
lvbu.fight(zhaoyun)
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202IQ7-10.jpg)
文章图片
提示:虽然这里只展示了一个类,但是我们应该能够发现,某个类的对象在调用方法时,不仅可以用和自身同一个类创建的对象来作为方法的参数值;还可以用另一个类创建的对象来作为方法的参数值
- 若调用 自身(对象) 属性:self.属性
- 若调用其他对象属性:其他对象.属性
需求:
- 士兵张三有一支AK47枪支
- 士兵可以开火
- 子弹可以发射
- 枪支上膛——增加子弹
文章图片
class Gun:
"""定义一个枪类"""
def __init__(self, model):
"""枪支型号"""
self.model = model
"""初始子弹数量为0"""
self.bullet_count = 0def __str__(self):
"""打印当前枪支属性"""
return "[枪支类型]:%s,[弹药数]:%d" % (self.model, self.bullet_count)def add_bullet(self, count):
"""增加子弹"""
if self.bullet_count == 30:
print("子弹已满,无须继续添加")
elif self.bullet_count < 30 < self.bullet_count + count:
print("增加数量过多,将填满弹匣,弹匣子弹:30")
self.bullet_count = 30else:
self.bullet_count += count
print("填充成功,子弹数+%d,弹匣子弹:%d" % (count, self.bullet_count))def shoot(self):
"""发射子弹"""
if self.bullet_count > 0:
self.bullet_count -= 1
print("发射成功,子弹数-1,剩余子弹:%d" % self.bullet_count)else:
print("弹匣为空,无法发射子弹")class Solider:
"""定义一个士兵类"""
def __init__(self, name, gun):
self.name = name
self.gun = gundef __str__(self):
return "[士兵姓名]:%s" % self.namedef fire(self):
self.gun.shoot()"""
基于枪和士兵的类,定义AK47和张三对象
由于张三需要AK47对象作为属性,因此应该先定义AK47
"""
ak47 = Gun("AK47")
zhangsan = Solider("张三", ak47)print(zhangsan)
print(ak47)ak47.add_bullet(29)
ak47.add_bullet(30)
ak47.add_bullet(1)i = 0
while i <= 30:
zhangsan.fire()i += 1
![Python基础|五、Python基础(类与对象)](http://img.readke.com/221009/02202GK1-12.png)
文章图片
9.补充:身份运算符 身份运算符用于比较两个对象的内存地址是否一致——是否是对同一对象的引用
在Python中针对 None 比较时,建议使用 is None 判断
运算符 | 描述 | 示例 |
---|---|---|
is | is是判断两个标识符是不是引用同一对象 | a is b,类似 id(a) == id(b) |
is not | is not是判断两个标识符是不是引用不同对象 | a is not b,类似于 id(a) != id(b) |
- is 用于判断两个变量引用对象是否为同一个
- == 用于判断引用变量的值是否相等
即对象才能访问对象自己的属性和方法,外界无法调用和访问
那么只需在定义属性/方法时只需在定义前加两条下划线 “_ _” 即可
self.__属性 = 属性值 定义私有属性【Python基础|五、Python基础(类与对象)】提示:私有属性和私有方法并不是真正意义上的不可访问,只是在其名称上加了改动,我们利用 _类名__属性/方法(一条下划线) 是可以访问到私有属性/方法的
def __方法(self…): 定义私有方法
上一篇文章
- 四、Python基础(变量与数据进阶)
- 六、Python基础(封装、继承、多态)
推荐阅读
- 蓝桥杯————成绩统计
- paddle课程|[Paddle领航团python基础课程大作业一]英文词频的统计任务
- 人工智能|驾驶员嗜睡分类 - 深度学习
- 指静脉识别|指静脉代码学习---7.图像增强
- python|基于PyTorch搭建CNN实现视频动作分类任务
- python|stn在mnist上的实现
- B站|B站马士兵python入门基础版详细笔记(5)
- flask|阿里云宝塔部署python-flask项目
- python|python爬虫实战演示