Tho*_*fin 6 python printing unicode stdout
我正在努力进行打印和unicode转换.这是在2.5 windows解释器中执行的一些代码.
>>> import sys
>>> print sys.stdout.encoding
cp850
>>> print u"é"
é
>>> print u"é".encode("cp850")
é
>>> print u"é".encode("utf8")
?®
>>> print u"é".__repr__()
u'\xe9'
>>> class A():
... def __unicode__(self):
... return u"é"
...
>>> print A()
<__main__.A instance at 0x0000000002AEEA88>
>>> class B():
... def __repr__(self):
... return u"é".encode("cp850")
...
>>> print B()
é
>>> class C():
... def __repr__(self):
... return u"é".encode("utf8")
...
>>> print C()
?®
>>> class D():
... def __str__(self):
... return u"é"
...
>>> print D()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)
>>> class E():
... def __repr__(self):
... return u"é"
...
>>> print E()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 0: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)
因此,当打印一个unicode字符串时,它不是__repr__()调用和打印的函数.
但是,当打印对象__str__()或__repr__()(如果__str__未实现)被调用时,则不会__unicode__().两者都无法返回unicode字符串.
但为什么?为什么如果__repr__()或__str__()返回一个unicode字符串,它不应该与我们打印unicode字符串时的行为相同吗?我换句话说:为什么print D()不同print D().__str__()
我错过了什么吗?
这些示例还显示,如果要打印以unicode字符串表示的对象,则必须将其编码为对象字符串(类型为str).但是为了良好的打印(避免使用"├®"),它取决于sys.stdout编码.
所以,我必须添加u"é".encode(sys.stdout.encoding)我的每个的__str__或__repr__方法?或者返回repr(u"é")?如果我使用滚边怎么办?是编码相同sys.stdout吗?
我的主要问题是使类"可打印",即print A()打印完全可读的内容(不使用\ x***unicode字符).以下是需要修改的错误行为/代码:
class User(object):
name = u"Luiz Inácio Lula da Silva"
def __repr__(self):
# returns unicode
return "<User: %s>" % self.name
# won't display gracefully
# expl: print repr(u'é') -> u'\xe9'
return repr("<User: %s>" % self.name)
# won't display gracefully
# expl: print u"é".encode("utf8") -> print '\xc3\xa9' -> ?®
return ("<User: %s>" % self.name).encode("utf8")
Run Code Online (Sandbox Code Playgroud)
谢谢!
Python 对给定的函数和方法没有很多语义类型约束,但它有一些,这里有一个:( __str__在Python 2.*中)必须返回一个字节字符串.像往常一样,如果找到'ascii'需要字节字符串的unicode对象,则会尝试使用当前的默认编码(通常)来尝试从相关的unicode对象生成所需的字节字符串.
对于此操作,任何给定文件对象的编码(如果有的话)都是无关紧要的,因为从中返回的内容__str__可能即将被打印,或者可能会受到完全不同且无关的处理.你打电话的目的__str__与呼叫本身及其结果无关; 通常,Python在确定操作的语义时不会考虑操作的"未来上下文"(操作完成后将对结果执行的操作).
这是因为Python并不总是知道你未来的意图,并试图尽量减少意外. print str(x)并且s = str(x); print s(在一次吞咽中对两次进行的操作相同)尤其必须具有相同的效果; 如果是第二种情况,如果str(x)无法有效地产生字节串(例如,x.__str__()不能),则会出现异常,因此在其他情况下也应该发生异常.
print本身(因为2.4,我相信),当提供一个unicode对象时,会考虑.encoding目标流的属性(如果有的话)(默认情况下sys.stdout); 尚未连接到任何给定目标流的其他操作不会 - 而且str(x)(即x.__str__())就是这样的操作.
希望这有助于说明令你烦恼的行为的原因......
编辑:OP现在澄清"我的主要问题是使类"可打印",即打印A()打印完全可读的内容(不使用\ x***unicode字符)." 这是我认为最适合该特定目标的方法:
import sys
DEFAULT_ENCODING = 'UTF-8' # or whatever you like best
class sic(object):
def __unicode__(self): # the "real thing"
return u'Pel\xe9'
def __str__(self): # tries to "look nice"
return unicode(self).encode(sys.stdout.encoding or DEFAULT_ENCODING,
'replace')
def __repr__(self): # must be unambiguous
return repr(unicode(self))
Run Code Online (Sandbox Code Playgroud)
也就是说,这种方法侧重于__unicode__作为类的实例自我格式化的主要方式 - 但是由于(在Python 2中)print调用__str__,它具有一个委托,__unicode__它在编码方面可以做到最好.不完美,但随后Python 2的print声明远非完美;-).
__repr__就其本身而言,必须努力明确,即不要以牺牲模糊性为代价来"看起来不错"(理想情况下,在可行的情况下,它应返回一个字节串,如果传递给它eval,将使实例等于现在的......远非总是可行的,但缺乏模糊性是和之间区别的绝对核心,我强烈建议尊重这种区别!).__str____repr__