Python基础|五、Python基础(类与对象)

五、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)面向对象
  • 在完成一个需求前,首先确定职责——要做的事情(方法)
  • 根据职责确定不同的对象,在对象中封装不同的方法(多个)
  • 最后的代码,就是顺序地让不同的对象调用不同的方法
  • 相比较函数,面向对象是更大的封装
二、类与对象 1.类的基本概念 类是对一群具有相同特征或者行为的事物的一个统称,是抽象的,不能直接使用
  • 特征被称为属性
  • 行为被称为方法
类就相当于制造飞机时的图纸,是一个模板,是负责创建对象的
2.对象的基本概念 对象是由类创建出来的一个具体存在,可以直接使用,由哪一个类创建出来的对象,就拥有在哪一个类中定义的属性和方法,对象就相当于用图纸(类)制造飞机
  • 在程序的开发中,应该先有类,然后有对象
3.类的设计 在使用面向对象开发前,应该首先分析需求,确定程序中应该包括哪些类
在程序开发中,要设计一个类,通常需要满足以下三要素:
  • 类名 这类事物的名字,应满足大驼峰命名法
  • 属性 这类事物应该具有怎么样的特征
  • 方法 这类事物应该具有怎么样的行为
  • 对对象的特征描述,通常可以定义成属性
  • 对象具有的行为(动词),通常可以定义为 __方法__
三、面向对象基础语法 1.dir内置函数 在Python中,使用内置函数 dir 传入标识符/数据,可以查看对象内的所有属性及方法
__方法名__ 所有以这种前后两个下划线格式命名的方法是Python提供的内置方法/属性
dir(对象名) 可以列出该对象中可以使用的所有属性及方法,它是以字符串列表的方式列出(横向)
注:由于方法较多,若直接 print(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基础(类与对象)
文章图片

在上述内置的方法中,有一些较为常用的:
序号 方法名 类型 作用
1 __new__ 方法 创建对象时,会被自动调用
2 __init__ 方法 对象初始化时,会被自动调用
3 __del__ 方法 对象被从内存中销毁前,会被自动调用
4 __str__ 方法 返回对象的描述信息,print函数输出使用
5 __doc__ 方法 查看函数/类中的方法的解释文档
例:__doc__方法可以列出函数的解释文档
def function(temp_num): """ 这是函数的解释文档:param temp_num: 函数的参数 :return: 没有返回值 """ print(temp_num)print(function.__doc__)

Python基础|五、Python基础(类与对象)
文章图片

2.定义简单的类(只包含方法)和创建对象 面向对象是相较于函数而言更大的封装,在一个类中封装多个方法,这样通过这个类创建出来的对象,就可以直接调用这些方法了
(1)定义简单的类的方法:
定义类的简单方法的结构示意图:
Python基础|五、Python基础(类与对象)
文章图片

  • 类名应当满足大驼峰命名法
(2)基于某个类创建对象的方法:
对象变量 = 类名() 即可为某个指定的类创建一个方法
(3)对象调用类中的方法:
对象.方法名(self, 参数列表) 调用类中的方法,这个类似于高级变量类型调用方法的语法
注:self 不传递参数
例:创建一个 PersonJob 职业类,根据这个类定义一个职业 driver,即可调用类中的方法
——这里暂时没有提到self,后面会说到
class PersonJob: """在类中定义多个方法""" def function1(self): print("工作内容")def function2(self): print("工作薪资")driver = PersonJob()driver.function1() driver.function2()

Python基础|五、Python基础(类与对象)
文章图片

注:在面向对象开发中,我们在 四、Python基础(变量进阶)中提到的引用的概念是同样适用的
3.方法中的self参数 实际上,self 保存的是对象的引用,即哪一个对象调用了类中的方法,self 就是哪一个对象的引用,它可以通过属性名来访问对象的属性
print(对象名) 即可查看指定对象所属的类和所引用的地址(十六进制)
Python基础|五、Python基础(类与对象)
文章图片

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基础(类与对象)
文章图片

创建类的完整结构示意图:
Python基础|五、Python基础(类与对象)
文章图片

补充:
  • 基于类创建的对象通常也称为类的实例
  • 创建对象的过程通常也称为实例化
  • 对象的属性通常也称为实例属性
  • 对象调用的方法通常也称为实例方法
5. __del__ 方法
  • 类似于 C++ 或 PHP 等语言的析构函数
__del__ 方法可以让对象在内存被释放前自动调用的最后一次函数,在内存被释放前执行的最后一项工作,执行完后即释放对象的内存
  • 我们知道,__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基础(类与对象)
文章图片

6. __str__ 方法 前面提到过,用 print(对象) 的默认输出格式是:输出这个对象是由哪一个类创建的,以及其在内存中引用的地址(十六进制)
Python基础|五、Python基础(类与对象)
文章图片

如果在开发中,希望使用 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基础(类与对象)
文章图片

提示:如果有多个类,则被使用的类应该先被创建
7.阶段小结(一):简单的三国杀 需求:
(1)定义一个武将类,它包括:
  • 属性——武将名、生命值、攻击力
  • 打印:输出武将的当前属性
  • 吃桃:生命值+1
  • 装备武器:武器名、武器增加攻击力数值
  • 攻击:攻击目标、目标生命值–=攻击方攻击力
  • 胜利提示,阵亡提示
(2)定义两个武将对象:吕布、赵云,初始生命值均为4
  • 游戏过程:
  • 打印双方武将属性
  • 吕布装备方天画戟,攻击力+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基础(类与对象)
文章图片

提示:虽然这里只展示了一个类,但是我们应该能够发现,某个类的对象在调用方法时,不仅可以用和自身同一个类创建的对象来作为方法的参数值;还可以用另一个类创建的对象来作为方法的参数值
  • 若调用 自身(对象) 属性:self.属性
  • 若调用其他对象属性:其他对象.属性
8.阶段小结(二):士兵突击 在这个案例中,我们将进一步深化对上述的提示的理解:一个类创建的对象的属性可以是另一个类创建的对象(练习重点
需求:
  • 士兵张三有一支AK47枪支
  • 士兵可以开火
  • 子弹可以发射
  • 枪支上膛——增加子弹
    Python基础|五、Python基础(类与对象)
    文章图片
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基础(类与对象)
文章图片

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 与 == 的区别:
  • is 用于判断两个变量引用对象是否为同一个
  • == 用于判断引用变量的值是否相等
10.补充:私有属性和私有方法 当一个对象中的某些属性或方法只希望为自身所用,而不希望被外界访问,即称为私有
即对象才能访问对象自己的属性和方法,外界无法调用和访问
那么只需在定义属性/方法时只需在定义前加两条下划线 “_ _” 即可
self.__属性 = 属性值 定义私有属性
def __方法(self…): 定义私有方法
【Python基础|五、Python基础(类与对象)】提示:私有属性和私有方法并不是真正意义上的不可访问,只是在其名称上加了改动,我们利用 _类名__属性/方法(一条下划线) 是可以访问到私有属性/方法的
上一篇文章
  • 四、Python基础(变量与数据进阶)
下一篇文章
  • 六、Python基础(封装、继承、多态)

    推荐阅读