__REPR __()関数の最適な出力タイプとエンコーディングプラクティス?

StackOverflow https://stackoverflow.com/questions/3627793

  •  26-09-2019
  •  | 
  •  

質問

最近、私は多くの問題を抱えています __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

ここに私を悩ませてきたいくつかの追加の問題があります、そして、私はそれらを解決する解決策を探しています:

  1. UTF-8端末への印刷は機能するはずです(私は持っています sys.stdout.encoding に設定 UTF-8, 、しかし、他のケースも機能した場合に最適です)。
  2. 出力をファイルに配管する(UTF-8でエンコードされた)機能するはずです(この場合、 sys.stdout.encodingNone).
  3. 多くの人のための私のコード __repr__() 現在、関数にはたくさんあります return ….encode('utf-8'), 、それは重いです。堅牢で軽いものはありますか?
  4. 場合によっては、私は醜い獣さえ持っています 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))
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top