Python中类内定义类的变量中的bug
2018-12-5
今天看到有人在类内的初始化函数__init_(self,…)之前定义类的变量:
不是很明白为什么要在__init__()之外先定义一个变量x。于是就自己做实验测试了一下,之前定义的x=1
和__init__()函数内的self.x=_x
有何区别。
如下方式定义类A,
1. 内外变量虽然有相同的变量名,但分配不同地址
定义了A的对象a=A(1)
,
可以看到a.x是经过__init__()函数初始化过的对象的变量,而A.x是类A本身的变量,与对象a并无关系。
用id()
函数查看了变量的地址,a.x
和A.x
的地址并不相同。2. 当内外变量值一致时,可能会是相同地址
当我再次定义一个A的对象b,b=A(2)
,查看b.x
的地址,发现id(b.x)=id(A.x)
。
如上面所显示的,b.x和A.x的地址竟然是一样的。
于是我又改变了b.x的值,
然后我又发现当我改变b.x的值为5,使其不等于A.x时,b.x的地址竟然又改变。
我就很不明白这是怎么一回事,后来在网上百度。看到其他网友关于id函数的解释:
引用链接:
也就是说,我们发现当a.x=A.x=2时,二者的内存是一样的,和类中变量的定义是无关的。只不过是python对于小型整数分配内存中的一种资源的共享。
然后,我就用大型的整数又做了一次实验:
令a.x=b.x=A.x=1000
,用id函数再次看三个变量的内存就发现它们是相互无关的。
就是这样了,以后还是可以放心大胆的在类内为类本身定义变量了。
/*----------更新 2019-4-21-----------*/
这里之所以小整数时内存会一样其实和__init__函数无关。这里涉及到了python的内存管理机制。
在python中所有的东西都是对象,整数也是。
比如a = 1
,在python看来,a是变量,而1是对象。前面的语句就是将a这个变量指向了对象1。python有个特别的机制,它会在解释器启动的时候事先分配好一些缓冲区,这些缓冲区部分是固定好取值,例如整数[-5, 256]的内存地址是固定的(一旦启动python程序,内存就分配好了,但下次启动分配的地址可能就变了)。所以a = 1
和b = 1
两个语句都是将a,b指向了整数1所在的内存地址,而python程序已经为1分配好了内存地址,所以a和b指向的地址是相同的。但如果a = 267
, b = 267
,a和b的内存地址就不是一样的。
另外,除了整数,python也为字符串设立了静态缓冲区,对于只包含字母和数字的字符串,地址也是固定不变的。