__repr __()功能的最佳输出类型和编码实践?
题
最近,我有很多麻烦 __repr__()
, format()
, 和编码。 应该输出 __repr__()
被编码还是是Unicode字符串? 是否有最好的编码 __repr__()
在python?我要输出的确实具有非ASCII字符。
我使用Python 2.x,并想编写可以轻松适应Python的代码。
# -*- 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__
)必须返回字符串对象,而不是unicode对象。在python3中,情况颠倒了, __repr__
和 __str__
必须返回Unicode对象,而不是字节(née字符串)对象:
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))
不隶属于 StackOverflow