66

最近、、、、およびエンコーディング __repr__()で多くの問題が発生しました。の出力はエンコードする必要がありますか、それともユニコード文字列にする必要がありますか?Python の結果に最適なエンコーディングはありますか?出力したいのは非ASCII文字です。format()__repr__()__repr__()

私はPython2.xを使用しており、Python3に簡単に適応できるコードを記述したいと考えています。

# -*- 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.encodingですNone)。
  3. __repr__()多くの関数の私のコードには現在多くのものがreturn ….encode('utf-8')あり、それは重いです。頑丈で軽いものはありますか?
  4. 場合によってはreturn ('<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')、オブジェクトの表現がデコードされ、フォーマット文字列に入れられてから再エンコードされるなど、醜い獣さえいます。私はそのような複雑な変化を避けたいと思います。

__repr__()これらのエンコーディングの質問に関してうまく動作する単純な関数を書くために、あなたは何をすることをお勧めしますか?

4

3 に答える 3

42

Python2では、__repr__(および__str__)はUnicodeオブジェクトではなく、文字列オブジェクトを返す必要があります。Python3では、状況が逆に__repr__なり__str__ 、バイト(文字列)オブジェクトではなく、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))
于 2010-09-02T14:01:23.790 に答える
6

__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}'
于 2012-12-12T21:10:09.467 に答える
1

私は次のような関数を使用します:

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))
于 2012-05-17T15:59:59.150 に答える