06_Python基础到实战一飞冲天(三)-python面向对象(六)–类属性和类方法和单例
一、类属性-05-使用对象名+类属性赋值语句会创建实例属性
1、使用对象名访问类属性的问题注意
- 如果使用
对象.类属性 = 值
赋值语句,只会 给对象添加一个属性,而不会影响到 类属性的值。
2、使用对象名访问类属性的问题 示例 代码(dzs_14_使用对象名访问类属性的问题.py):
# dzs_14_使用对象名访问类属性的问题.pyclass Tool(object):# 使用赋值语句,定义类属性,记录创建工具对象的总数count = 0def __init__(self, name):self.name = name# 针对类属性做一个计数+1Tool.count += 1# 创建工具对象
tool1 = Tool("斧头")
tool2 = Tool("榔头")
tool3 = Tool("铁锹")# 如果使用 对象.类属性 = 值 赋值语句,只会给对象添加一个属性,而不会影响到类属性的值
tool1.count = 99
print("这是对象 count = %d " % tool1.count)# 通过类名访问类属性
print("现在创建了 %d 个工具类" % Tool.count)
3、示例:
二、类方法-01-基本语法
1、类方法
1)类属性 就是针对 类对象 定义的属性。
* 使用 赋值语句 在 class
关键字下方可以定义 类属性。
* 类属性 用于记录 与这个类相关 的特征。
2)类方法 就是针对 类对象 定义的方法
* 在 类方法 内部可以直接访问 类属性 或者调用其他的 类方法。
3)类方法语法如下
@classmethod
def 类方法名(cls):pass
2、类方法 语法 说明:
1)类方法需要用 修饰器 @classmethod
来标识,告诉解释器这是一个类方法。
2)类方法的 第一个参数 应该是 cls
。
* 由 **哪一个类** 调用的方法,方法内的 `cls` 就是 **哪一个类的引用**。
* 这个参数和 **实例方法** 的第一个参数是 `self` 类似。
* **提示** 使用其他名称也可以,不过习惯使用 `cls`。
3)通过 类名. 调用 类方法,调用方法时,不需要传递 cls
参数
4)在方法内部
* 可以通过 cls.
访问类的属性。
* 也可以通过 cls.
调用其他的类方法。
三、类方法-02-案例演练
1、类方法示例需求
1)定义一个 工具类。
2)每件工具都有自己的 name
。
3)需求 —— 在 类 封装一个 show_tool_count
的类方法,输出使用当前这个类,创建的对象个数。
在类方法内部,可以直接使用
cls
访问 类属性 或者 调用类方法
2、类方法 示例 代码(dzs_15_类方法.py):
# dzs_15_类方法.pyclass Tool(object):# 使用赋值语句,定义类属性,记录创建工具对象的总数count = 0@classmethoddef show_tool_count(cls):"""显示工具对象的总数"""print("工具类的总数 %d" % cls.count)def __init__(self, name):self.name = name# 针对类属性做一个计数+1Tool.count += 1# 创建工具对象
tool1 = Tool("斧头")
tool2 = Tool("榔头")
# tool3 = Tool("铁锹")# 如果使用 对象.类属性 = 值 赋值语句,只会给对象添加一个属性,而不会影响到类属性的值
tool1.count = 9
print("这是对象 count = %d " % tool1.count)# 通过类名访问类方法
Tool.show_tool_count()
3、示例:
四、静态方法-01-应用场景和定义方式
1、 静态方法
1)在开发时,如果需要在 类 中封装一个方法,这个方法:
* 既 **不需要** 访问 **实例属性** 或者调用 **实例方法**。
* 也 **不需要** 访问 **类属性** 或者调用 **类方法**。
2)这个时候,可以把这个方法封装成一个 静态方法
3)静态方法语法如下
@staticmethod
def 静态方法名():pass
4)静态方法 需要用 修饰器 @staticmethod
来标识,告诉解释器这是一个静态方法。
5)通过 类名. 调用 静态方法。
2、静态方法 示例 代码(dzs_16_静态方法.py):
# dzs_16_静态方法.pyclass Dog(object):@staticmethoddef run():# 不需要访问实例属性也不需要访问类属性的方法print("狗在跑...")# 通过 类名. 静态方法名 调用静态访求,不需要创建对象
Dog.run()
3、示例:
五、方法综合-01-案例分析
1、方法综合案例:需求分析
1)设计一个 Game
类。
2)属性:
* 定义一个 类属性 top_score
记录游戏的 历史最高分。
* 定义一个 实例属性 player_name
记录 当前游戏的玩家姓名。
3) 方法:
* 静态方法 show_help
显示游戏帮助信息。
* 类方法 show_top_score
显示历史最高分。
* 实例方法 start_game
开始当前玩家的游戏。
4)主程序步骤
* 1) 查看帮助信息。
* 2) 查看历史最高分。
* 3) 创建游戏对象,开始游戏。
2、方法综合案例 类和方法示例图:
六、方法综合-02-案例演练
1、方法综合案例演练 示例 代码(dzs_17_方法综合案例.py):
# dzs_17_方法综合案例class Game(object):"""Game"""# 游戏最高分,类属性top_score = 0def __init__(self, player_name):self.player_name = player_name@staticmethoddef show_help():print("帮助信息:让僵尸走进房间")@classmethoddef show_top_score(cls):print("游戏最高分 high score: %d " % cls.top_score)def start_game(self):print("[%s] 开始游戏..." % self.player_name)# 使用类名.修改历史最高分Game.top_score = 999# 1. 查看游戏帮助
Game.show_help()# 2. 查看游戏最高分
Game.show_top_score()# 3. 创建游戏对象,开始游戏
game = Game("小明")game.start_game()# 4. 游戏结束,查看游戏最高分
Game.show_top_score()
2、示例:
七、方法综合-03-确定方法类型的套路
1、方法综合案例小结
1)实例方法 —— 方法内部需要访问 实例属性。
* 实例方法 内部可以使用 类名. 访问类属性。
2) 类方法 —— 方法内部 只 需要访问 类属性。
3)静态方法 —— 方法内部,不需要访问 实例属性 和 类属性。
2、提问
如果方法内部 即需要访问 实例属性,又需要访问 类属性,应该定义成什么方法?
答案
1)应该定义 实例方法。
2)因为,类只有一个,在 实例方法 内部可以使用 类名. 访问类属性。
八、单例-01-设计模式和单例设计模式概念
1、单例学习 目标
- 单例设计模式
__new__
方法- Python 中的单例
2、设计模式
1)设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题 的成熟的解决方案。
2)使用 设计模式 是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
3、单例设计模式
1)单例目的 —— 让 类 创建的对象,在系统中 只有 唯一的一个实例
2)每一次执行 类名()
返回的对象,内存地址是相同的。
4、单例设计模式的应用场景
1)音乐播放 对象
2)回收站 对象
3)打印机 对象
九、单例-02-new方法的作用
1、 __new__
方法
1)使用 类名() 创建对象时,Python
的解释器 首先 会 调用 __new__
方法为对象 分配空间。
2) __new__
是一个 由 object
基类提供的 内置的静态方法,主要作用有两个:
* 1) 在内存中为对象 **分配空间**。
* 2) **返回** 对象的引用。
3) Python
的解释器获得对象的 引用 后,将引用作为 第一个参数,传递给 __init__
方法。
重写
__new__
方法 的代码非常固定!
4)重写 __new__
方法 一定要 return super().__new__(cls)
- 否则 Python 的解释器 得不到 分配了空间的 对象引用,就不会调用对象的初始化方法。
5)注意:__new__
是一个静态方法,在调用时需要 主动传递 cls
参数。
2、对象分配空间和初始化 示例图:
十、单例-03-重写new方法
1、单例 示例代码(dzs_18___new__方法.py):
# dzs_18___new__方法.pyclass MusicPlayer(object):def __new__(cls, *args, **kwargs):# 1.创建对象时,new方法会被自动调用print("创建对象,分配空间")# 2.为对象分配空间instance = super().__new__(cls)# 3.返回对象的引用。如果不返回任何结果,初始化方法就拿不到内存地址return instancedef __init__(self):print("初始化音乐播放对象")player = MusicPlayer()
print(player)
2、示例:
上一节关联链接请点击:
05_Python基础到实战一飞冲天(三)-python面向对象(五)–多继承多态和类属性