これは、CPython 実装が文字列リテラルをキャッシュする方法の癖です。同じ内容の文字列リテラルは、同じ文字列オブジェクトを参照できますが、そうである必要はありません。Python 識別子で許可されている文字のみが含まれているため、そうでない'string'
場合は自動的にインターンされます。それが彼らが選んだ基準である理由はわかりませんが、そうです。Python のバージョンや実装が異なると、動作が異なる場合があります。'string '
'string'
CPython 2.7 ソース コードのstringobject.h
28 行目:
文字列のインターン (ob_sstate) は、指定された値を持つ文字列オブジェクトが 1 つだけ存在することを確認しようとするため、等価テストは 1 つのポインター比較になります。これは通常、Python 識別子に「似ている」文字列に制限されていますが、組み込みの intern() を使用して任意の文字列のインターンを強制できます。
これを行うコードは次のObjects/codeobject.c
とおりです。
/* Intern selected string constants */
for (i = PyTuple_Size(consts); --i >= 0; ) {
PyObject *v = PyTuple_GetItem(consts, i);
if (!PyString_Check(v))
continue;
if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
continue;
PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
}
また、インターンは、Python バイトコード コンパイラによる文字列リテラルのマージとは別のプロセスであることに注意してください。a
コンパイラにとのb
割り当てを一緒にコンパイルさせると (たとえば、モジュールまたは に配置することによって) 、 と が同じ文字列になることがif True:
わかります。a
b