a = 5
aa = 5
b = 5.1
bb = 5.1
c = False
cc = False
d = None
dd = None
strone = "hello"
strtwo = "hello"
listone = [1, 2]
listtwo = [1, 2]
tupleone = (1, 2)
tupletwo = (1, 2)
tuplethree = (1, [2, 3])
tuplefour = (1, [2, 3])
print(a is aa) # True
print(b is bb) # True
print(c is cc) # True
print(d is dd) # True
print(strone is strtwo) # True
print(listone is listtwo) # False
print(tupleone is tupletwo) # True
print(tuplethree is tuplefour) # False
注意:如上面代码,我们知道数字类型,布尔类型,NoneType 类型和字符串类型的值相同则 id 相同;list 类型的值相同而 id 不同;里面成员里面不含有变量的 tuple 类型对应的值相同则 id 相同,如果 tuple 里面的成员(或者成员的成员的...无限递归)出现有变量的话,虽然值相同,但 id 不同。 我们来好好分析一下:1.早期的 Python 解释器对布尔类型,数字类型,NoneType类型的变量都是通过分配不同的内存存储的,自从 Python 2.7 之后,解释器做了优化,所以那些类型只要值相同,所在的内存是同一个; 2.其实字符串类型的值是放在常量区,相同的字符串所在内存地址是一样的,也就是只要变量指向的字符串值相同,用的是同一块内存; 3.对于 list 类型所有的 Python 版本包括 Python 2 采用的都是一样的内存机制,就是无论 list 值是什么,在每一次创建的时候 Python 解释器都会重新分配一块内存; 4.对于 tuple 类型,Python 3.6(包括)之后的版本则会判断里面的成员(或者成员的成员的...无限递归)是否有变量,如果有的话则重新分配内存,否则共用一块内存,而 Python 2 采用的机制是只要创建一个新的 tuple 对象都会重新分配一块内存 。
大家注意到,我们上面所举的例子都是右值赋值的方式,如果是变量赋值呢,我们看下如下代码。
a = 5
aa = a
b = 5.1
bb = b
c = False
cc = c
d = None
dd = d
strone = "hello"
strtwo = strone
listone = [1, 2]
listtwo = listone
tupleone = (1, 2)
tupletwo = tupleone
tuplethree = (1, [2, 3])
tuplefour = tuplethree
print(a is aa) # True
print(b is bb) # True
print(c is cc) # True
print(d is dd) # True
print(strone is strtwo) # True
print(listone is listtwo) # True
print(tupleone is tupletwo) # True
print(tuplethree is tuplefour) # True
我只说一句:Python 解释器所有的变量之间赋值都是采用的浅拷贝方案,浅拷贝就是把赋值运算符=右边的变量里面所指向值的内存地址直接赋值给左边的变量。
如果你想深拷贝可以使用python的copy.deepcopy函数,如下例子:
import copy
list1 = [1, 43]
list2 = copy.deepcopy(list1)
list1[0] = 22
print(list1)
print(list2)
参考:高级运算符www.birdpython.com