一、总体目录
- 1.1、类的结构
- 1.2、类属性和实例属性
- 1.3、类方法和静态方法
二、类的结构
- 2.1、术语 -实例
- 使用面相对象开发,第 1 步 是设计 类
- 使用 类名() 创建对象,创建对象 的动作有两步:
- (1) 在内存中为对象 分配空间
- (2) 调用初始化方法
__init__
为 对象初始化对象创建后,内存 中就有了一个对象的 实实在在 的存在 —实例
- 创建出来的
对象
叫做类 的 实例
- 创建对象的
动作
叫做实例化
- 对象的
属性
叫做实例属性
- 对象调用的
方法
叫做实例方法
- 在程序执行时
- 对象各自拥有自己的
实例属性
- 调用对象方法,可以通过
self.
结论
- 每一个对象 都有自己
独立的内存空间
,保存各自不同的属性- 多个对象的方法,
在内存中只有一份
,在调用方法时,需要把对象的引用
传递到方法内部
- 2.2 类是一个特殊的对象
Python 中 一切皆对象:
- class AAA: 定义的类属于 类对象
- obj1 = AAA() 属于 实例对象
- 在程序运行时,
类
同样会被加载到内存
- 在 Python 中,
类
是一个特殊的对象 ——类对象
- 在程序运行时,
类对象
在内存中只有一份
,使用一个类
可以创建出很多个对象实例
- 除了封装
实例
的属性
和方法
外,类对象
还可以拥有自己的属性
和方法
- 类属性
- 类方法
- 通过
类名.
的方式可以访问类的属性
或者调用类的方法
三、类属性 和 实例属性
- 3.1 概念和使用
- 类属性 就是给 类对象 中定义的 属性
- 通常用来记录 与这个类相关 的特征
- 类属性 不会用于记录 具体对象的特征
- 如下例子,定义一个 类属性
count
,记录创建类的个数
class Tool(object): # 使用赋值语句,定义类属性,记录创建工具对象的总数 count = 0 def __init__(self,name): # 针对类属性做一个计数+1 Tool.count += 1 self.name = name # 创建工具对象 tool1 = Tool("斧头") tool2 = Tool("镰刀") # 知道使用 Tool 类到底创建了多少个对象? print("工具的数量是 %d"%Tool.count)
- 类属性的创建:在类的下面使用赋值语句,等号左边是类属性的名字,右边是类属性的初始值 ;使用是:
类名.属性名
, 如上面的 count
- 3.2、属性的获取机制-
向上查找机制
- 在 Python 中 属性的获取 存在一个 向上查找机制(下面代码 Tool.count 与 tool2.count)
class Tool(object): # 使用赋值语句,定义类属性,记录创建工具对象的总数 count = 0 def __init__(self,name): # 针对类属性做一个计数+1 Tool.count += 1 self.name = name # 创建 工具对象 tool1 = Tool("斧头") tool2 = Tool("镰刀") # 知道使用 Tool 类到底创建了多少个对象? # print("工具的数量是 %d"%Tool.count) print("工具的数量是 %d"% tool2.count)
- 说明查找机制:首先上面的代码
tool2.count
,tools这个对象是没有count
这个属性的,这时候就会去类的属性里面去找有没有count
,如果类里面也没有的话就报错 - 由上面可知,要访问类属性有两种方式:
- 类名.类属性
- 对象.类属性 (不推荐)
- 注意:如果使用
对象.类属性 = 值
赋值语句,只会给对象添加一个属性
,而不会影响到类属性的值
如上面的代码修改后(tool2.count
就不靠谱了,仅仅是为 tool2添加了一个属性而已)
# 创建 工具对象 tool1 = Tool("斧头") tool2 = Tool("镰刀") # 知道使用 Tool 类到底创建了多少个对象? print("工具的数量是 %d"%Tool.count) tool2.count = 100 print("工具的数量是 %d"% tool2.count)
四、类方法 和 静态方法
- 4.1、类方法
- 类属性 就是针对 类对象 定义的属性
- 使用
赋值语句
在class
关键字下方可以定义类属性
类属性
用于记录与这个类相关
的特征
类方法
就是针对类对象
定义的方法
- 在
类方法
内部可以直接访问类属性
或者调用其他的类方法
- 语法如下
@classmethod def 类方法名(cls): pass
- 类方法需要用
修饰器
@classmethod
来标识,告诉解释器这是一个类方法
- 类方法的
第一个参数
应该是cls
- 由
哪一个类
调用的方法,方法内的cls
就是哪一个类的引用
- 这个参数和
实例方法
的第一个参数是self
类似 提示
使用其他名称也可以,不过习惯使用cls
- 通过
类名.
调用类方法
,调用方法时,不需要传递cls
参数 在方法内部
- 可以通过
cls.
访问类的属性 - 也可以通过
cls.
调用其他的类方法
在类方法内部,可以直接使用
cls
访问类属性
或者 `调用类方法
- 4.2、类方法定义以及使用的案例
需求:定义一个Person类
,定义一个类属性:name
,类方法:run
跑步,在类方法run
里面打印类属性name
class Person(object): name = "" @classmethod def run(cls): print("%s 会跑"%cls.name) Person.name = "小米" Person.run()
- 4.3、静态方法
- 在开发时,如果需要在
类
中封装一个方法,这个方法:
- 既
不需要
访问实例属性
或者调用实例方法
- 也
不需要
访问类属性
或者调用类方法
- 语法如下(不需要任何参数的)
@staticmethod def 静态方法名(): pass
静态方法
需要用 修饰器@staticmethod
来标识,告诉解释器这是一个静态方法
- 通过
类名.
调用 静态方法 - 实例:
class Baby(object): @staticmethod def cry(): # 不需要访问实例属性也不需要访问类属性的方法 print("小孩在哭...") Baby.cry()
五、综合案例
- 5.1、需求
- (1)、设计一个
Game
类,模拟吃鸡游戏
- (2)、属性:
- 定义一个 类属性
top_score
记录游戏的 历史最高分 - 定义一个 实例属性
player_name
记录 当前游戏的玩家姓名
- (3)、方法:
- 静态方法
show_help
显示游戏帮助信息 - 类方法
show_top_score
显示历史最高分 - 实例方法
start_game
开始当前玩家的游戏
- (4)、主程序步骤
- 查看帮助信息
- 查看历史最高分
- 创建游戏对象,开始游戏
class Game(object): # 游戏最高分,类属性 top_score = 0 @staticmethod def show_help(): print("帮助信息:吃鸡游戏开始啦") @classmethod def show_top_score(cls): print("游戏最高分是 %d" % cls.top_score) def __init__(self, player_name): self.player_name = player_name def start_game(self): print("[%s] 开始游戏..." % self.player_name) # 使用类名.修改历史最高分 Game.top_score = 10000 # 1. 查看游戏帮助 Game.show_help() # 2. 查看游戏最高分 Game.show_top_score() # 3. 创建游戏对象,开始游戏 game = Game("二郎神") game.start_game() # 4. 游戏结束,查看游戏最高分 Game.show_top_score()
- 5.2、总结
- 实例方法 —— 方法内部需要访问 实例属性
- 实例方法 内部可以使用
类名.
访问类属性
- 类方法 —— 方法内部 只 需要访问 类属性
- 静态方法 —— 方法内部,不需要访问 实例属性 和 类属性