web-dev-qa-db-ja.com

Python "string_escape" vs "unicode_escape"

ドキュメントによると 、組み込み文字列エンコードstring_escape

Pythonソースコードの文字列リテラルとして適切な文字列を生成します

... unicode_escape

PythonソースコードでUnicodeリテラルとして適切な文字列を生成します

したがって、それらはほぼ同じ動作をする必要があります。しかし、彼らは一重引用符を異なって扱うように見えます:

>>> print """before '" \0 after""".encode('string-escape')
before \'" \x00 after
>>> print """before '" \0 after""".encode('unicode-escape')
before '" \x00 after

string_escapeは一重引用符をエスケープしますが、Unicodeはエスケープしません。私が簡単にできると仮定することは安全ですか?

>>> escaped = my_string.encode('unicode-escape').replace("'", "\\'")

...そして予想される動作を取得しますか?

編集:非常に明確にするために、期待される動作はリテラルとして適切なものを得ています。

24
Mike Boers

_unicode-escape_の実装とCPython 2.6.5ソースのunicode reprの私の解釈によれば、そうです。 repr(unicode_string)unicode_string.encode('unicode-escape')の唯一の違いは、引用符のラッピングと、使用された引用符のエスケープです。

両方とも同じ関数_unicodeescape_string_によって駆動されます。この関数はパラメーターを取り、その唯一の機能は、折り返し引用符の追加とその引用符のエスケープを切り替えることです。

22
Mike Boers

0≤c <128の範囲内では、'のみがCPython 2.6の唯一の違いです。

>>> set(unichr(c).encode('unicode_escape') for c in range(128)) - set(chr(c).encode('string_escape') for c in range(128))
set(["'"])

この範囲外では、2つのタイプは交換できません。

>>> '\x80'.encode('string_escape')
'\\x80'
>>> '\x80'.encode('unicode_escape')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can’t decode byte 0x80 in position 0: ordinal not in range(128)

>>> u'1'.encode('unicode_escape')
'1'
>>> u'1'.encode('string_escape')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: escape_encode() argument 1 must be str, not unicode

Python 3.x、strはUnicodeのみを保存できるため、string_escapeエンコーディングは存在しません。

12
kennytm