2010-11-27 48 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

默認情況下,解釋器只爲小整數或字符串創建一個共享對象。