在python中变量名相当于一个指针,为变量赋值相当于是将指针指向了这个值的内存空间。
那么如果执行foo1=foo2=4.3的时候相当于(参考《Python核心编程》第二版4.5.2)
foo1 = 4.3
foo2 = foo1
按照这种理解,那么是不是如果继续执行
foo1=5.0
foo2 也会变成5.0呢?当然不会。(详细程序验证在下面)
但是,如果变量不是整型呢?
我们执行
foo1=foo2=[1,2,3]
foo1[1]=5
这时候foo2 的值是多少?当然也是[1,5,3](和foo1一样)。为什么呢?
有一种解释:Python在处理整型、字符型的时候使用值传递,所以foo2的值只是和foo1的值相等,但不是同一个内存空间。而在处理浮点型、列表等类型是使用的是地址传递,也就是说foo2和foo1指向的是同一个内存空间。(《Python核心编程》第二版没有说的这么细,但是在例子中可以看到浮点型确实是这样理解的)。
此外,如果foo1=3,foo2=2+1,foo这两个变量的地址又是如何确定呢?在《Python核心编程》第二版中,这两个变量指向的仍然不是同一地址。
真的是这样吗?经过测试我发现,Python语言各种类型的传递方式其实是一致的。首先在一个变量刚被赋值时,首先要出现一个常量,这个值存放在内存空间。当foo2=foo1时,foo2的地址也指向了这个常量的空间。上面的图是没有错的。
但是,但是,当我给foo1改变值的时候,系统会在生成一个常量空间,让foo1指向这个新的空间。这就是为什么foo2的值没有变化的原因。浮点数也是这样的,没有区别。
但是,为什么列表不可以呢?其实列表也是同一个原理,但是上面例子改变的是列表内部的一个值(只不过Python允许你去改变列表内部罢了),你要是给foo1=[4,5,6],foo2是不会变的。如果你能改变整型内部的二进制位,我想foo1和foo2也会一起变化的。
最后,如果foo1=3,foo2=2+1,foo2会抛弃2和1,直接指向3的地址空间,也就是说foo1和foo2指向同一空间。
当然,我也不敢说《Python核心编程》就写错了,也许是Python做了不变化呢。这个谁要是知道请告诉我。
我的环境:Python 2.7.13 |Anaconda 4.4.0 (64-bit)| (default, May 11 2017, 13:17:26)
'''
@author:fengjiexyb
@time:2017-09-05
This file is used to check how are variables in Python assigned
1.check Whether the memory addresses that a and b's are consistent
2.check whether the memory address that b's is changed when a is changed
3.check whether the value that b's is changed when a is changed
4.check contain integer,float,list and other about add
'''
print '-----------1.Integer--------------'
print 'integer original'
aInt=3
bInt=aInt
print ' aInt=%d,bInt=%d'%(aInt,bInt)
print ' aInt memory address: %s\n bInt memory address: %s'%(id(aInt),id(bInt))
print 'integer changed'
aInt=4
cInt=4
print ' aInt=%d,bInt=%d,cInt=%d'%(aInt,bInt,cInt)
print ' aInt memory address: %s\n bInt memory address: %s\n cInt memory address:%s'%(id(aInt),id(bInt),id(cInt))
print '-----------2.Float--------------'
print 'Float original'
aFloat=3.1
bFloat=aFloat
print ' aFloat=%f,bFloat=%f'%(aFloat,bFloat)
print ' aFloat memory address: %s\n bFloat memory address: %d'%(id(aFloat),id(bFloat))
print 'Float changed'
aFloat=4.1
cFloat=4.1
print ' aFloat=%f,bFloat=%f,cFloat=%f'%(aFloat,bFloat,cFloat)
print ' aFloat memory address: %s\n bFloat memory address: %s\n cFloat memory address:%s'%(id(aFloat),id(bFloat),id(cFloat))
print '----------3.List---------------'
print 'list original'
aList=[1,2,3]
bList=aList
print ' aList=',aList,'bList=',bList
print ' aList memory address: %s\n bList memory address: %s'%(id(aList),id(bList))
print 'List changed'
aList[1]=10
print ' aList=',aList,'bList=',bList
print ' aList memory address: %s\n bList memory address: %s'%(id(aList),id(bList))
print '----------4.List2---------------'
print 'list original'
aList=[1,2,3]
bList=aList
print ' aList=',aList,'bList=',bList
print ' aList memory address: %s\n bList memory address: %s'%(id(aList),id(bList))
print 'List changed'
aList=[10,11,12]
print ' aList=',aList,'bList=',bList
print ' aList memory address: %s\n bList memory address: %s'%(id(aList),id(bList))
print '-----------5.Integer add--------------'
print 'integer original'
aInt=4
cInt=2+2
print ' aInt=%d,cInt=%d'%(aInt,cInt)
print ' aInt memory address: %s\n cInt memory address:%s'%(id(aInt),id(cInt))
执行结果:
-----------1.Integer--------------
integer original
aInt=3,bInt=3
aInt memory address: 6578984
bInt memory address: 6578984
integer changed
aInt=4,bInt=3,cInt=4
aInt memory address: 6578960
bInt memory address: 6578984
cInt memory address:6578960
-----------2.Float--------------
Float original
aFloat=3.100000,bFloat=3.100000
aFloat memory address: 6639816
bFloat memory address: 6639816
Float changed
aFloat=4.100000,bFloat=3.100000,cFloat=4.100000
aFloat memory address: 6639840
bFloat memory address: 6639816
cFloat memory address:6639840
----------3.List---------------
list original
aList= [1, 2, 3] bList= [1, 2, 3]
aList memory address: 45289032
bList memory address: 45289032
List changed
aList= [1, 10, 3] bList= [1, 10, 3]
aList memory address: 45289032
bList memory address: 45289032
----------4.List2---------------
list original
aList= [1, 2, 3] bList= [1, 2, 3]
aList memory address: 45430024
bList memory address: 45430024
List changed
aList= [10, 11, 12] bList= [1, 2, 3]
aList memory address: 45289032
bList memory address: 45430024
-----------5.Integer add--------------
integer original
aInt=4,cInt=4
aInt memory address: 6578960
cInt memory address:6578960