栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

浅析python不同变量内存机制对类变量的影响

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

浅析python不同变量内存机制对类变量的影响

结论:python中列表型的类变量如果不初始化会出现与实例对象同步变化的现象

测试代码:

class A:
 x = []
 y = 0
 z = ''
 def __init__(self):
    #self.x=[]
    #self.y=0
    #self.z=''
    pass
 def add(self):
    self.x.append('1')
    self.y+=1
    self.z+='1'
a=A() 
print (a.x,a.y,a.z,id(a.x),id(a.y),id(a.z))
print (A.x,A.y,A.z,id(A.x),id(A.y),id(A.z))
b=A()
print (b.x,b.y,b.z)
print (A.x,A.y,A.z)
a.add()
print (a.x,a.y,a.z,id(a.x),id(a.y),id(a.z))
print (A.x,A.y,A.z,id(A.x),id(A.y),id(A.z))
b.add()
print (b.x,b.y,b.z,id(b.x),id(b.y),id(b.z))
print (A.x,A.y,A.z,id(A.x),id(A.y),id(A.z))

输出:
[] 0 2143136050752 140710602131072 2142814937840
[] 0 2143136050752 140710602131072 2142814937840
[] 0
[] 0
[‘1’] 1 1 2143136050752 140710602131104 2142816448816
[‘1’] 0 2143136050752 140710602131072 2142814937840
[‘1’, ‘1’] 1 1 2143136050752 140710602131104 2142816448816
[‘1’, ‘1’] 0 2143136050752 140710602131072 2142814937840

现象总结

在python定义列表型类变量时如果没有对其初始化,即没有部署其对应的实例变量,就会出现类变量与实例中的变量同步变化的情况。

而这种情况在其他类型的数据,如实数型和字符串型的变量上就不会出现。

原因

修改后的代码:

class A:
 x = []
 y = 0
 z = ''
 def __init__(self):
    self.x=[]
    self.y=0
    self.z=''
    #pass
 def add(self):
    self.x.append('1')
    self.y+=1
    self.z+='1'
a=A() 
print (a.x,a.y,a.z,id(a.x),id(a.y),id(a.z))
print (A.x,A.y,A.z,id(A.x),id(A.y),id(A.z))
b=A()
print (b.x,b.y,b.z)
print (A.x,A.y,A.z)
a.add()
print (a.x,a.y,a.z,id(a.x),id(a.y),id(a.z))
print (A.x,A.y,A.z,id(A.x),id(A.y),id(A.z))
b.add()
print (b.x,b.y,b.z,id(b.x),id(b.y),id(b.z))
print (A.x,A.y,A.z,id(A.x),id(A.y),id(A.z))

输出:
[] 0 2503856091328 140710626772608 2503401874160
[] 0 2503856091264 140710626772608 2503401874160
[] 0
[] 0
[‘1’] 1 1 2503856091328 140710626772640 2503402336560
[] 0 2503856091264 140710626772608 2503401874160
[‘1’] 1 1 2503409909184 140710626772640 2503402336560
[] 0 2503856091264 140710626772608 2503401874160

这样的结果才是正常的。

经过对比两个输出结果,不难发现,在构建实例a时,加入了初始化操作,才会为列表变量x分配新的内存空间,若没有这步初始化,在后续对其进行append()操作后也不会改变其类变量和实例中变量的内存地址,它们始终占用一块内存。
这实际与python的内存管理机制有关,在对一个列表进行append(),extend()或+=等操作时,并不会改变这个列表的地址。因此,在上述未初始化代码中,add()操作始终是在对同一个列表操作,这就导致了类列表变量会与实例对象中的列表对象同步变化。

但是,为什么实数型变量y即使没有初始化,也始终正常呢?
再次观察两次结果,可以发现,实例化对象中的变量y无论是否初始化,在add()操作前,都指向同一块地址。这实际也是python内存管理的一个特性,对于实数、字符串这种占用内存较小的变量类型会根据值为其分配内存。也就是因为这个原因,使得在实例对象中改变变量的值后,该对象所拥有的该变量内存地址发生了变化,但是在类中,该简单变量依旧指向最初的地址。

python初学者,如有错误疏漏,敬请指正!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/324384.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号