1. ホーム
  2. python

[解決済み] Python 2.6でunicode_literalsを使用する際の注意点は?

2022-11-26 01:06:18

質問

私たちはすでにPython 2.6でコードベースを動作させています。 Python 3.0の準備のために、私たちは追加を開始しました。

from __future__ import unicode_literals

を私たちの .py ファイルに追加しています。 他の誰かがこれをやっていて、(おそらく多くの時間をかけてデバッグした後に)明白でないゴチャに遭遇したことがあるのかどうか気になります。

どのように解決するのですか?

ユニコード文字列を扱う際に発生する問題の主な原因は、utf-8でエンコードされた文字列とユニコード文字列を混在させたときです。

たとえば、次のようなスクリプトを考えてみましょう。

two.py

# encoding: utf-8
name = 'helló wörld from two'

one.py

# encoding: utf-8
from __future__ import unicode_literals
import two
name = 'helló wörld from one'
print name + two.name

を実行したときの出力 python one.py です。

Traceback (most recent call last):
  File "one.py", line 5, in <module>
    print name + two.name
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)

この例では two.name をインポートしていないので、(ユニコードではなく)utf-8でエンコードされた文字列になっています。 unicode_literals をインポートしていないため、unodeではありません。 one.name はユニコード文字列です。両方を混ぜると、pythonはエンコードされた文字列をデコードして(asciiと仮定して)unicodeに変換しようとし、失敗します。もし print name + two.name.decode('utf-8') .

文字列をエンコードしておいて、後でそれらを混在させようとすると、同じことが起こります。 例えば、このように動作します。

# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
    html = html.encode('utf-8')
print 'DEBUG: %s' % html

出力します。

DEBUG: <html><body>helló wörld</body></html>

しかし import unicode_literals を追加すると、そうではなくなります。

# encoding: utf-8
from __future__ import unicode_literals
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
    html = html.encode('utf-8')
print 'DEBUG: %s' % html

出力します。

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    print 'DEBUG: %s' % html
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 16: ordinal not in range(128)

失敗するのは 'DEBUG: %s' はユニコード文字列であるため、python は html . このプリントを修正する方法はいくつかあります。 print str('DEBUG: %s') % html または print 'DEBUG: %s' % html.decode('utf-8') .

ユニコード文字列を使用する際の潜在的なゴチャゴチャを理解する助けになれば幸いです。