Python3学习之路~6.3 类变量 VS 实例变量
类变量 VS 实例变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #Author:Zheng Na # 实例里面可以查询、增加、删除、修改实例变量 class Role: # 类名 # 类变量 name = '我是类name' n = 1 n_list = [] def __init__( self ,name,role,weapon,life_value = 100 ,money = 15000 ): # 构造函数 # 在实例化时做一些类的初始化的工作 # 开辟一块内存,将下面这些变量传进去 self .name = name # 实例变量(静态属性),作用域就是实例本身(r1和r2的实例变量不能共享) self .role = role self .weapon = weapon self .life_value = life_value self .money = money def buy_gun( self ,gun_name): # 类的方法(动态属性) print ( "%s just bought %s" % ( self .name,gun_name)) def got_shot( self ): print ( "ah...I got shot..." ) print (Role.n) #1 在没有实例化之前,就可以打印类变量,说明类变量存放在类的内存里 r1 = Role( "Alex" , "Policeman" , "AK47" ) # 生成一个角色,把一个类变成一个具体对象的过程叫实例化 r2 = Role( "Jack" , "terrorist" , 'B22' ) r1.buy_gun( "AK47" ) #Alex just bought AK47 r1.got_shot() #ah...I got shot... # 通过实例调用一个变量时,先在实例中寻找这个变量,如果找不到,再去类中寻找 print (r1.n) #1 实例化之后,通过实例对象也可以调用类变量(先去实例中寻找变量n,找不到,再去类中寻找,找到了!) print (r1.name) #Alex 当实例变量与类变量同名时,先去找实例变量,再去找类变量 r1.name = 'Rose' #实例化后再修改变量值,修改了实例变量 print (r1.name) #Rose print (Role.name) #我是类name r1.bullet_prove = True # 实例化后可以再增加一个属性,仅给r1增加了属性,r2没有这个属性 print (r1.bullet_prove) # True # print(r1.weapon) # AK47 del r1.weapon # 可以删除属性 # print(r1.weapon) # 报错 r1.n = "改类变量" # r1改了类变量,r2没改,内部实际上是在r1的内存里创建了一个新的变量,实际上不影响类变量本身 print (r1.n) # 改类变量 print (r2.n) # 1 print (Role.n) # 1 # 在类中修改变量,效果就是在类内存中存放的类变量由n=1变为n='ABC' # 在实例r1调用变量n时,先在r1内存中寻找n,找到了,返回其值“改类变量” # 在实例r2调用变量n时,先在r2内存中寻找n,没找到,再去类的内存中寻找n,此时类变量n的值已修改,于是返回修改后的值。 Role.n = "ABC" #在类中修改变量 print (r1.n) # 改类变量 print (r2.n) # ABC # 当类变量为list时,无论实例r1或r2修改其值,改变的都是类变量的值,因为他们用的是同一个内存变量 r1.n_list.append( "from r1" ) r2.n_list.append( "from r2" ) print (Role.n_list) # ['from r1', 'from r2'] print (r1.n_list) # ['from r1', 'from r2'] print (r2.n_list) # ['from r1', 'from r2'] |
类变量的作用
类变量的作用就是保存大家共用的属性,节省开销(省内存)。
比如某一个系统中的所有用户均是中国人,那么国籍这个变量就可以写为类变量。
如下代码中的2个Person类所示,虽然最终结果时一样的,但是使用Person1类时,每实例化一个对象,就会开辟一块内存,传一个默认参数cn进去。中国有14亿人口,就会存14亿个参数,浪费内存。使用Person2类时,类变量cn仅存在于类的内存空间中,所有的实例均调用这个变量,节省开销。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #Author:Zheng Na class Person1: def __init__( self ,name,age,addr,cn = "china" ): #默认参数 self .name = name self .age = age self .addr = addr self .cn = cn class Person2: cn = 'china' #类变量 def __init__( self ,name,age,addr): self .name = name self .age = age self .addr = addr p1 = Person1( "xiaoming" , 21 , "山东" ) print (p1.cn) # china p2 = Person2( "xiaoming" , 21 , "山东" ) print (p2.cn) # china |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通