2010-11-27 8 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を見つけるために、次のコードの塊を試してみました。彼らは同じイドを持っていてはいけませんか?誰かがその仕組みを説明できるかどうか疑問に思っていましたか?

おかげ

答えて

4

同じIDが正確同じオブジェクトを意味するが、パイソンの実装は、それが喜ばとして不変オブジェクトの作成を最適化するために自由です。例えば、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に関係なくオブジェクトの等価性をテストできます。

+0

タプルリテラルはコンパイル時に作成されます。それらはコードオブジェクトの 'co_consts'に格納され、' LOAD_CONST'オペレーションを使って一つのステップでロードされます。それらの作成に関わる時間はコンパイル時です。彼らはおそらく、おそらく単にデフォルトで拘束されるべきです。 – aaronasterling

3

文字列リテラルはinternedことができるので、あなたは、文字列と同じIDを取得します。タプルはインターンされていないので、タプルのIDは同じではありません。

変更可能なデータ構造体は合理的に格納できません(読み込み:そうすると非常に混乱します)ので、文字列が変更可能であれば、それらを格納することはできません。しかし、これはすべての不変のデータ構造が保留されていることを意味するものではありません。

+0

"文字列リテラルがインターンされているため、文字列と同じIDを取得します。"これは3.xですか? – khachik

+0

最後に調べてから何か変わっていない限り、文字列は常にインターンになっているというのは、あまり真実ではありません。 Pythonは実際にはそうしない権利を留保していますが、一般に辞書のような短い文字列を使用します。 – aaronasterling

+0

@aaron:文字列は必ず受け入れられるとは限りませんが、文字列リテラルが存在するという印象を受けました。少なくとも簡単なテストでは、1001文字の文字列リテラルがPython 2.6.6でインターンされていることがわかりました。 – sepp2k

1

Immatableは、クラスのインスタンスを変更できないことを意味します。例えば:

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

デフォルトでは、インタープリタは小さい整数または文字列に対して1つの共有オブジェクトを作成します。