16

Python に問題があり、string.format()Unicode 文字列を渡すのに問題があります。これはこの古い質問に似ていますが、私の場合、テスト コードがlogging.info()呼び出しではなく印刷で爆発する点が異なります。同じ Unicode 文字列オブジェクトをロギング ハンドラに渡すと、問題なく動作します。

これは、古い%フォーマットと同様に失敗しますstring.format()。問題が文字列オブジェクトであることを確認し、印刷が端末とうまくやり取りしないようにするために、印刷する前にフォーマットされた文字列を変数に割り当ててみました。

def unicode_test():
    byte_string = '\xc3\xb4'
    unicode_string = unicode(byte_string, "utf-8")
    print "unicode object type: {}".format(type(unicode_string))
    output_string = "printed unicode object: {}".format(unicode_string)
    print output_string

if __name__ == '__main__':
    unicode_test()

文字列オブジェクトは、ASCII を取得していると想定しているようです。

% python -V
Python 2.7.2

% python ./unicodetest.py
unicode object type: <type 'unicode'>
Traceback (most recent call last):
  File "./unicodetest.py", line 10, in <module>
    unicode_test()
  File "./unicodetest.py", line 6, in unicode_test
    output_string = "printed unicode object: {}".format(unicode_string)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf4' in position 0: ordinal not in range(128)

Unicode としてキャストしようoutput_stringとしても、違いはありません。

output_string = u"印刷された Unicode オブジェクト: {}".format(unicode_string)

ここで何か不足していますか?文字列オブジェクトのドキュメントは、私が使用しようとしているときにこれが機能するはずであることを明確に示しています。

4

1 に答える 1

23

いいえ、これは機能しないはずです(ドキュメントのそのように書かれている部分を引用できますか?)が、フォーマットパターンがユニコードの場合(または、デモートする代わりにパターンをユニコードに「プロモート」する古いフォーマットの場合)は機能するはずです。 '引数)。

>>> x = "\xc3\xb4".decode('utf-8')
>>> x
u'\xf4'
>>> x + 'a'
u'\xf4a'
>>> 'a' + x
u'a\xf4'
>>> 'a %s' % x
u'a \xf4'
>>> 'a {}'.format(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec 
  can't encode character u'\xf4' in position 0: ordinal not in range(128)
>>> u'a {}'.format(x)
u'a \xf4'
>>> print u"Foo bar {}".format(x)
Foo bar ô

編集:printコンソールのエンコーディングを使用してUnicode文字列をエンコードできない場合、この行は機能しない可能性があります。たとえば、私のWindowsコンソールでは次のようになります。

>>> import sys
>>> sys.stdout.encoding
'cp852'
>>> u'\xf4'.encode('cp852')
'\x93'

UNIXコンソールでは、これはロケール設定に関連している可能性があります。|(シェルで使用する場合のように)出力をリダイレクトした場合も失敗します。この問題のほとんどはPython3で修正されています。

于 2012-12-02T22:50:47.417 に答える