__REPR __()関数の最適な出力タイプとエンコーディングプラクティス?
質問
最近、私は多くの問題を抱えています __repr__()
, format()
, 、およびエンコーディング。 の出力が必要です __repr__()
エンコードされますか、それともユニコード文字列になりますか? 結果に最適なエンコーディングはありますか __repr__()
Pythonで?私が出力したいのは、ASCII以外の文字を持っています。
私はPython 2.xを使用しており、Python 3に簡単に適応できるコードを書きたいと思っています。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function # The 'Hello' literal represents a Unicode object
ここに私を悩ませてきたいくつかの追加の問題があります、そして、私はそれらを解決する解決策を探しています:
- UTF-8端末への印刷は機能するはずです(私は持っています
sys.stdout.encoding
に設定UTF-8
, 、しかし、他のケースも機能した場合に最適です)。 - 出力をファイルに配管する(UTF-8でエンコードされた)機能するはずです(この場合、
sys.stdout.encoding
はNone
). - 多くの人のための私のコード
__repr__()
現在、関数にはたくさんありますreturn ….encode('utf-8')
, 、それは重いです。堅牢で軽いものはありますか? - 場合によっては、私は醜い獣さえ持っています
return ('<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')
, 、つまり、オブジェクトの表現がデコードされ、フォーマットの文字列に入れられてから再エンコードされます。このような複雑な変換を避けたいと思います。
シンプルに書くために何をすることをお勧めしますか __repr__()
これらのエンコードの質問に関してうまく振る舞う機能?
解決
Python2で、 __repr__
(と __str__
)ユニコードオブジェクトではなく、文字列オブジェクトを返す必要があります。 Python3では、状況が逆転し、 __repr__
と __str__
バイト(née文字列)オブジェクトではなく、Unicodeオブジェクトを返す必要があります。
class Foo(object):
def __repr__(self):
return u'\N{WHITE SMILING FACE}'
class Bar(object):
def __repr__(self):
return u'\N{WHITE SMILING FACE}'.encode('utf8')
repr(Bar())
# ☺
repr(Foo())
# UnicodeEncodeError: 'ascii' codec can't encode character u'\u263a' in position 0: ordinal not in range(128)
Python2では、本当に選択肢がありません。の返品値のエンコーディングを選択する必要があります __repr__
.
ちなみに、あなたは読んだことがありますか printfails wiki?他の質問に直接答えることはできませんが、特定のエラーが発生する理由を明らかにするのに役立つと思いました。
使用するとき from __future__ import unicode_literals
,
'<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')
より簡単に書くことができます
str('<{}>').format(repr(x))
仮定します str
にエンコードします utf-8
あなたのシステムで。
それなし from __future__ import unicode_literals
, 、式は次のように書くことができます。
'<{}>'.format(repr(x))
他のヒント
デコレーターが管理できると思います __repr__
正気な方法での互換性。これが私が使用しているものです:
from __future__ import unicode_literals, print_function
import sys
def force_encoded_string_output(func):
if sys.version_info.major < 3:
def _func(*args, **kwargs):
return func(*args, **kwargs).encode(sys.stdout.encoding or 'utf-8')
return _func
else:
return func
class MyDummyClass(object):
@force_encoded_string_output
def __repr__(self):
return 'My Dummy Class! \N{WHITE SMILING FACE}'
次のような関数を使用します。
def stdout_encode(u, default='UTF8'):
if sys.stdout.encoding:
return u.encode(sys.stdout.encoding)
return u.encode(default)
それから私 __repr__
関数は次のようになります:
def __repr__(self):
return stdout_encode(u'<MyClass {0} {1}>'.format(self.abcd, self.efgh))