2017-03-09 13 views
3
>>> a = "zzzzqqqqasdfasdf1234" 
>>> b = "zzzzqqqqasdfasdf1234" 
>>> id(a) 
4402117560 
>>> id(b) 
4402117560 

しかし文字列はキャッシュされていますか?

>>> c = "[email protected]#$" 
>>> d = "[email protected]#$" 
>>> id(c) == id(d) 
False 
>>> id(a) == id(b) 
True 

なぜ同じid()の結果を得る唯一の割り当て文字列?

編集:私は "文字列"だけで "ASCII文字列"を置き換えます。フィードバックありがとう

+4

これらは両方ともASCII文字列です... – mgilson

+1

ここでインターン(キャッシング)はCPythonの実装の詳細であり、_lots_に依存しています。これをスクリプトに入れると、REPLで実行した場合とは異なる結果になることに注意してください。 – mgilson

答えて

6

ASCII以外のものではありません(あなたの「非ASCII」はまだASCIIです。英数字ではなく句読点です)。実装の詳細としてCPython、interns string constants that contain only "name characters"。この場合の「名前文字」は、正規表現のエスケープと同じものを意味します\w:英数字とアンダースコア。

注:これはいつでも変更することができ、決して頼りにすべきではありません。使用するだけの最適化です。推測で

、この選択は、インターンがしばしば関与辞書検索がポインタの比較を行うと回避終わることを意味し、文字列リテラルの一握り、など、をキー getattrsetattrdict Sを使用するコードを最適化するために行われました文字列を全く比較しません(2つの文字列が両方とも格納されている場合、それらは定義上は同じオブジェクトか等しくないので、データを完全に読み取ることはできません)。

+0

ありがとうございます。 「インターン手段」についてもっと詳しく説明できますか? – ner0

+0

@ ner0:ショートバージョン:国際化された文字列は、グローバルルックアップテーブル内の文字列であり、各値に対して一意のIDを保証します。 2つの非内部文字列は同じ値を持ち、完全に異なるオブジェクトであることができますが、両方の文字列が内部にある場合は発生しません。つまり、2つの内部文字列を比較するのではなく、文字を1つずつチェックします。 Pythonは、ポインタチェックのスピードルックアップのために、すべてのクラス、属性、変数(通常はローカルスコープには使用されていませんが)、関数などの名前をインターンします。 – ShadowRanger

+0

また、空の文字列とすべての長さ1のASCII(おそらくlatin-1?)文字列を自動でインターンする(またはそれに近いものを実行します)ので、明示的にインターンさせることなくシングルトンにします。ここでも、これは実装の詳細です。パフォーマンス、メモリ使用量、コードシンプルさなどを改善すると考えれば、いつでも変更することができます – ShadowRanger

関連する問題