本篇的主要内容是自己的手动操作的学习记录,关于个名词的理论概念参见以下文章:
Python 实例方法、类方法、静态方法的区别与作用
作者:蔷薇Nina
出处:博客园
python3类对象、实例对象、类属性、实例属性
作者:te小星星
出处:简书
1.类属性:类外面,可以通过实例对象.类属性和类名.类属性进行调用。类里面,通过self.类属性和类名.类属性进行调用。
2.实例属性 :类外面,可以通过实例对象.实例属性调用。类里面,通过self.实例属性调用。
3.实例属性就相当于局部变量。出了这个类或者这个类的实例对象,就没有作用了。
4.类属性就相当于类里面的全局变量,可以和这个类的所有实例对象共享。
5.类方法修改类属性,实例方法修改实例属性,静态方法和他们都没有关联的时候使用,也就是不需要传参的时候使用。
类属性 & 实例属性
class Tool:
# 类属性,记录创建的工具实例的数量
count = 0
# 类属性,记录工具总重量
weight = 0
def __init__(self, name, weight):
# 实例属性
self.name = name
# 同名实例属性,访问读取时是类属性,赋值时创建实例属性
# self.weight = self.weight + weight
# self.weight(类属性) + weight
# self.weight (创建实例属性)=...
self.weight += weight
# 工具数量+1
Tool.count += 1
# 工具总重叠加
Tool.weight += weight
# 创建实例
tool1 = Tool("榔头", 10)
tool2 = Tool("锤子", 5)
tool3 = Tool("老虎钳", 3)
# 输出工具对象的总数
print("工具对象总数:%d" % Tool.count)
print()
# 由于在初始化时,创建了同名的实例属性
# 该处不是类属性
# 每次都以总重量(类属性)的基础上+自身重量
# 实例属性将不是各自的实际重量
# 为避免Python数值常量池(-5~256)对结果的影响,
# 可将类属性的初值设为1000
print(tool1.weight)
print(tool2.weight)
print(tool3.weight)
print(Tool.weight)
print("id(tool1.weight):%d" % id(tool1.weight))
print("id(tool2.weight):%d" % id(tool2.weight))
print("id(tool3.weight):%d" % id(tool3.weight))
print("id(Tool.weight):%d" % id(Tool.weight))
print()
# 访问读取时是类属性
print(tool3.count)
print(Tool.count)
print("id(tool3.count):%d\nid(Tool.count):%d" % (id(tool3.count), id(Tool.count)))
print()
# 通过实例给类属性赋值时,只会动态添加/修改实例属性
# 不会修改类属性的值
tool3.count = 1
print(tool3.count)
print(Tool.count)
print("id(tool3.count):%d\nid(Tool.count):%d" % (id(tool3.count), id(Tool.count)))
print()
执行结果:
工具对象总数:3
10
15
18
18
id(tool1.weight):8791483802736
id(tool2.weight):8791483802896
id(tool3.weight):8791483802992
id(Tool.weight):8791483802992
3
3
id(tool3.count):8791483802512
id(Tool.count):8791483802512
1
3
id(tool3.count):8791483802448
id(Tool.count):8791483802512
为排除数值常量池对结果的影响,将类属性weight的初值设为1000,再执行代码中的以下片段
# 可将类属性的初值设为1000
print(tool1.weight)
print(tool2.weight)
print(tool3.weight)
print(Tool.weight)
print("id(tool1.weight):%d" % id(tool1.weight))
print("id(tool2.weight):%d" % id(tool2.weight))
print("id(tool3.weight):%d" % id(tool3.weight))
print("id(Tool.weight):%d" % id(Tool.weight))
结果如下:
1010
1015
1018
1018
id(tool1.weight):32006000
id(tool2.weight):32005840
id(tool3.weight):32006032
id(Tool.weight):32005872
可以看出,前三者都是与类属性无关的实例属性
实例方法 & 类方法 & 静态方法
import random
import time
class Game:
# 类属性 历史最高分
top_score = 0
def __init__(self, username):
self.username = username
@staticmethod
def show_help():
print("帮助信息:游戏名:xxx,版本v1.0")
@classmethod
def show_top_score(cls):
print("历史最高分:%d" % cls.top_score)
def start(self):
print("开始游戏")
print("游戏进行中", end="")
for i in range(3):
for j in range(6):
print(".", end="")
time.sleep(0.21)
print("\b" * 6, end="")
print("......Game Over")
score = random.randint(0, 100)
print("%s游戏得分:%d" % (self.username, score))
# 更新游戏最高分记录
if Game.top_score < score:
Game.top_score = score
Game.show_help()
print()
# 实例可以访问类属性和类方法
game = Game("一叶知秋")
game.show_help()
game.show_top_score()
print()
game.start()
Game.show_top_score()
# 类名访问实例方法会报错————缺少参数'self'
# Game.start()
执行结果
帮助信息:游戏名:xxx,版本v1.0
帮助信息:游戏名:xxx,版本v1.0
历史最高分:0
开始游戏
游戏进行中......Game Over
一叶知秋游戏得分:88
历史最高分:88