2010-11-27 125 views
3

我对可变和不可变对象之间的区别有点困惑。我想下面的代码块找对象的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

编号相同意味着确切相同的对象,但是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如何。

3

你得到的字符串相同的ID,因为字符串文字可interned。你不会得到元组的相同id,因为元组没有被限制。

可变数据结构不能合理地实现(读取:这样做会导致非常混乱的行为),所以如果字符串是可变的,它们就不能被实现。但是,这并不意味着所有不可变数据结构都将被实施。

+0

“你得到与字符串相同的id,因为字符串文字是被拦截的。”这是3.x吗? – khachik 2010-11-27 19:22:24

+0

字符串总是被禁用是不正确的,除非自从我上次查看它之后发生了一些变化。 Python保留不这样做的权利,尽管在实践中它通常使用看起来像字典键的短字符串。 – aaronasterling 2010-11-27 19:28:33

1

Immatable意味着你不能改变类的实例。例如:

salad = ["Lettuce","Tomato","Onion","Tuna"] 
fruit = ("Apple","Banana","Cherry","Fig","Grapefruit") 
salad[3] = "Cheese" # works 
fruit[3] = "Orange" # error message 
1

默认情况下,解释器只为小整数或字符串创建一个共享对象。