最近、私は__repr__()
、format()
、およびエンコーディングに関して多くの問題を抱えています。 __repr__()
の出力をエンコードするか、Unicode文字列にする必要がありますか? Pythonの__repr__()
の結果に最適なエンコードはありますか?出力したいのは非ASCII文字です。
Python 2.xを使用していて、Python 3に簡単に適応できるコードを記述したい。したがって、プログラムは
_# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function # The 'Hello' literal represents a Unicode object
_
ここに私を悩ませてきたいくつかの追加の問題があります、そして私はそれらを解決する解決策を探しています:
sys.stdout.encoding
_を_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__
)は、Unicodeオブジェクトではなく、文字列オブジェクトを返す必要があります。 Python3では、状況が逆になり、__repr__
と__str__
はバイト(文字列)オブジェクトではなく、ユニコードオブジェクトを返す必要があります。
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))