不可变类型的ID
我对可变对象和不可变对象之间的区别有点困惑。我试着运行了一段代码来找出对象的ID:
tuple1 = ('Object1', 'Object2')
print id(tuple1)
tuple2 = ('Object1', 'Object2')
print id(tuple2)
list1 = ['Object1', 'Object2']
print id(list1)
list2 = ['Object1', 'Object2']
print id(list2)
string1 = "Foo bar"
print id(string1)
string2 = "Foo bar"
print id(string2)
我发现字符串的ID是一样的,列表的ID是不同的,而元组的ID也不同。难道它们不应该有相同的ID吗?我想知道这个是怎么回事?
谢谢
4 个回答
1
不可变的意思是你不能改变这个类的实例。举个例子:
salad = ["Lettuce","Tomato","Onion","Tuna"]
fruit = ("Apple","Banana","Cherry","Fig","Grapefruit")
salad[3] = "Cheese" # works
fruit[3] = "Orange" # error message
3
你会发现字符串的ID是一样的,因为字符串字面量可以被“内部化”。而元组的ID就不一样,因为元组是不能被内部化的。
一个可变的数据结构是不能被合理地内部化的(换句话说,内部化会导致非常混乱的行为),所以如果字符串是可变的,它们就不能被内部化。不过,这并不意味着所有不可变的数据结构都是内部化的。
5
相同的ID意味着是完全相同的对象,但Python的实现可以自由地优化不可变对象的创建方式。例如,在CPython 2.6.6中,小整数对象是被缓存的,所以:
>>> x=256
>>> x is 256
True
>>> x=1024
>>> x is 1024
False
[NOTE: 'is' tests for object identity (same ID)]
这并不意味着在其他实现中结果也会一样。某个实现可能会缓存不可变的元组,但哪些元组是常见的呢?如果像你说的那样,所有相同的元组返回相同的ID,那么程序创建的每个元组都必须被缓存,每次新创建一个元组时都得去缓存中查找一下之前是否已经创建过,这样会很耗时间。
使用==
来测试对象是否相等,而不管它们的ID是什么。