5

Python 2.7で等しいUnicode文字列を作成すると、「通常の」文字列のようにメモリ内の同じ場所を指さない理由を誰かが説明していることを知っています。

>>> a1 = 'a'
>>> a2 = 'a'
>>> a1 is a2
True

さて、それは私が期待したことでしたが、

>>> ua1 = u'a'
>>> ua2 = u'a'
>>> ua1 is ua2
False

なぜ?どうやって?

4

2 に答える 2

3

通常の文字列はインターンされていると思いますが、ユニコード文字列はインターンされていません。この簡単なテストは私の理論(Python 2.6.6)をサポートしているようです。

>>> intern("string")
'string'
>>> intern(u"unicode string")

Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    intern(u"unicode string")
TypeError: intern() argument 1 must be string, not unicode
于 2013-03-13T18:49:21.960 に答える
2

通常の文字列は、インターンされることが保証されていません。ある場合もあるし、そうでない場合もあります。ルールは複雑でバージョン固有であり、意図的に文書化されていません。

Pythonは、良いアイデアである場合はいつでも、小さくて一般的に使用されるオブジェクトをインターンしようとするという事実に頼ることができます。そして、どちらかまたはその逆に依存するコードを書くと、a1 is a2最も不便なときはいつでも壊れてしまいます。

これ以上のものが必要な場合は、関心のある実装のバージョンのソースを確認する必要があります。CPythonの場合、詳細は主に2.62.7、3.3の内部stringobject.cにありますunicodeobject.c

もちろん、後者のファイルは2.xにも存在します(unicodeタイプを定義しているstrため、3.xのタイプとは異なります)。2.7のソースから、文字列を呼び出すことができない場合でも、文字列のインターンある程度サポートされていることがわかります。一見すると、2.7はインターンされた文字列を処理できるように見えますが、それらを作成することはありません。unicodeinternunicode

一方、3.3は、オブジェクトがUTF-8、UTF-16、またはUTF-32ストレージを指すことができるため、物事をさらに楽しくしstrます。これらはインターンされる可能性がありますが、古いスタイルのUnicodeAPIを使用するコードは最終的に新しいコピー。したがって、たとえa1 is a2、あなたが彼らのキャラクターを手に入れようとしても、彼らは異なるバッファを持っているかもしれません。

Pythonが文字列をインターンすることを選択するのはいつですか?しかし、繰り返しになりますが、重要なのはソースです。

于 2013-03-13T19:00:58.227 に答える