タイプid
(python 2.7))のオブジェクトのstr
について何かが私を困惑させます。str
タイプは不変なので、作成された後は常に同じid
になることを期待してください。自分の言い回しはあまり上手ではないので、代わりに入力シーケンスと出力シーケンスの例を投稿します。
_>>> id('so')
140614155123888
>>> id('so')
140614155123848
>>> id('so')
140614155123808
_
その間、それは常に変化します。ただし、その文字列を指す変数を指定すると、状況が変化します。
_>>> so = 'so'
>>> id('so')
140614155123728
>>> so = 'so'
>>> id(so)
140614155123728
>>> not_so = 'so'
>>> id(not_so)
140614155123728
_
したがって、変数がその値を保持すると、IDがフリーズするように見えます。実際、_del so
_および_del not_so
_の後で、id('so')
の出力が再び変化し始めます。
これはnot(小さい)整数の場合と同じ動作です。
不変性と同じid
の間に実際の関係はないことを知っています。それでも、私はこの行動の原因を解明しようとしています。私はpythonの内部に精通している誰かが私ほど驚かないと信じているので、私は同じ点に到達しようとしています...
異なる文字列で同じことを試みると、異なる結果が得られました...
_>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
>>> id('hello')
139978087896384
_
今それはis等しい...
この動作は、Pythonインタラクティブシェルに固有です。pyファイルに次のコードを追加した場合:
print id('so')
print id('so')
print id('so')
それを実行すると、次の出力が表示されます。
2888960 2888960 2888960
CPythonでは、文字列リテラルは定数として扱われ、上記のスニペットのバイトコードで確認できます。
2 0 LOAD_GLOBAL 0 (id)
3 LOAD_CONST 1 ('so')
6 CALL_FUNCTION 1
9 PRINT_ITEM
10 PRINT_NEWLINE
3 11 LOAD_GLOBAL 0 (id)
14 LOAD_CONST 1 ('so')
17 CALL_FUNCTION 1
20 PRINT_ITEM
21 PRINT_NEWLINE
4 22 LOAD_GLOBAL 0 (id)
25 LOAD_CONST 1 ('so')
28 CALL_FUNCTION 1
31 PRINT_ITEM
32 PRINT_NEWLINE
33 LOAD_CONST 0 (None)
36 RETURN_VALUE
same定数(つまり、同じ文字列オブジェクト)が3回読み込まれるため、IDは同じです。
最初の例では、文字列'so'
の新しいインスタンスが毎回作成されるため、IDが異なります。
2番目の例では、文字列を変数にバインドし、Pythonは文字列の共有コピーを維持できます。
動作を理解するより簡単な方法は、次の データ型と変数 を確認することです。
セクション「文字列の特殊性」では、例として特殊文字を使用して質問を説明します。
したがって、Pythonはインターン文字列が保証されていませんが、同じ文字列を頻繁に再利用するため、is
は誤解を招く可能性があります。id
またはis
。
これを実証するために、少なくともPython 2.6で新しい文字列を強制する方法を発見しました:
>>> so = 'so'
>>> new_so = '{0}'.format(so)
>>> so is new_so
False
そしてもう少しPython探査:
>>> id(so)
102596064
>>> id(new_so)
259679968
>>> so == new_so
True