我有一个从JSON文件中读取一些数据的对象。一些JSON数据是拉丁语1个字符的字符串,例如:
"name" : "frisée"
我将此对象字符串化为一个表,其中包含从JSON对象读取的一些字符串。如果我写这个:
def __str__(self): # Never mind the details, what matters is that I use __str__
ts = [p + (count,) for p, count in self.counts.items()]
ts.sort(key=lambda x:(x[2], x[0], x[1]))
return "\n".join(["%s\t%s\t%s" % (t[0], t[1], t[2]) for t in ts])
然后尝试运行print MyObject()
我收到错误:
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 9112: ordinal not in range(128)
但是,如果我这样写:
def to_string(self):
ts = [p + (count,) for p, count in self.counts.items()]
ts.sort(key=lambda x:(x[2], x[0], x[1]))
return "\n".join(["%s\t%s\t%s" % (t[0], t[1], t[2]) for t in ts])
然后运行print MyObject().to_string()
一切正常。正确打印“é”字符。
为什么__str__
的行为与to_string
不同?如何正确打印__str__
版本?
我尝试了encode
的各种迭代但无济于事。
答案 0 :(得分:1)
您的__str__
正在返回 unicode
类型值; JSON字符串始终是Unicode。但是,__str__
result must always return a bytestring, so type str
。如果你不这样做,Python会为你调用str()
结果,这意味着它会使用默认的ASCII编解码器隐式编码任何Unicode。
对结果进行明确编码:
def __str__(self):
ts = [p + (count,) for p, count in self.counts.items()]
ts.sort(key=lambda x:(x[2], x[0], x[1]))
return u'\n'.join([u'\t'.join(t[:2]) for t in ts]).encode('utf8')
或使用__unicode__
method代替。但print
不会调用此方法。您必须明确使用print unicode(MyObject())
。
print
知道如何正确编码unicode
字符串,前提是您的终端配置正确。它将使用sys.stdout.encoding
显式编码您的Unicode数据。这就是MyObject().to_string()
有效的原因。