__repr __()函数的最佳输出types和编码实践?

最近,我在__repr__()format()和编码方面遇到了很多麻烦。 __repr__()的输出应该被编码还是一个unicodestring? 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 

以下是一些困扰我的附加问题,我正在寻找解决scheme:

  1. 打印到一个UTF-8terminal应该工作(我有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')丑陋野兽,的对象被解码,放入格式化string,然后重新编码。 我想避免这种复杂的转变。

为了编写简单的__repr__()函数,对于这些编码问题,你会推荐怎么做呢?

在Python2中, __repr__ (和__str__ )必须返回一个string对象,而不是一个unicode对象。 在Python3中,情况相反, __repr____str__必须返回unicode对象,而不是byte(néestring)对象:

 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中,你并没有真正的select。 你必须为__repr__的返回值select一个编码。

顺便说一下,你读了PrintFails维基 ? 它可能不会直接回答你的其他问题,但我确实发现它有助于阐明为什么发生某些错误。


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 ,expression式可以写成:

 '<{}>'.format(repr(x)) 

我认为装饰者可以以一种理智的方式pipe理__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))