print obj和print obj之间的Python差异。_str__()[至少使用Unicode?]
我了解到,调用print obj和print obj之间的Python差异。_str__()[至少使用Unicode?],python,unicode,Python,Unicode,我了解到,调用print obj将调用obj.\uu str\uu(),这将反过来返回一个字符串以打印到控制台。现在我遇到了一个Unicode的问题,我无法打印任何非ascii字符。我得到了典型的“ascii超出范围”的东西 在试验过程中,以下各项起到了作用: print obj.__str__() print obj.__repr__() 这两个函数的作用完全相同(\uu str\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()只返
print obj
将调用obj.\uu str\uu()
,这将反过来返回一个字符串以打印到控制台。现在我遇到了一个Unicode的问题,我无法打印任何非ascii字符。我得到了典型的“ascii超出范围”的东西
在试验过程中,以下各项起到了作用:
print obj.__str__()
print obj.__repr__()
这两个函数的作用完全相同(\uu str\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu()
只返回self.\uuuuuuuuuuuuu repr。什么不起作用:
print obj
该问题仅在使用ascii范围以外的字符时出现。最终的解决方案是在\uuu str\uuu()
中执行以下操作:
现在它适用于所有部件。我现在的问题是:区别在哪里?为什么它现在能工作?我明白如果什么都没用,为什么现在能用。但是,为什么只有顶部有效,而底部无效呢
操作系统是Windows 7 x64,带有默认的Windows命令提示符。此外,据报告编码为cp850
。要理解python,这是一个更一般的问题。我的问题已经解决了,但我不是100%满意,主要是因为现在调用str(obj)
将生成一个未按我希望的方式编码的字符串
# -*- coding: utf-8 -*-
class Sample(object):
def __init__(self):
self.name = u"üé"
def __repr__(self):
return self.name
def __str__(self):
return self.name
obj = Sample()
print obj.__str__(), obj.__repr__(), obj
卸下最后一个obj
,它就会工作。保留它,它就会崩溃
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
首先,如果你看一下,\uuu str\uuuuuuuuuuuu
和\uuuuuuu repr\uuuuuu
有不同的目的,应该创建不同的输出。因此,从\uuuu str\uuuu
调用\uuuu repr\uuuu
并不是最好的解决方案
其次,print
将调用\uuuu str\uuuu
并且不会接收非ascii字符,因为,print
无法猜测如何转换非ascii字符
最后,在Python2.x的最新版本中,\uuuuuunicode\uuuuu
是为对象创建字符串表示的首选方法。这里面有一个有趣的解释
所以,要想真正回答这个问题,你可以做如下事情:
class Sample(object):
def __init__(self):
self.name = u"\xfc\xe9"
# No need to implement __repr__. Let Python create the object repr for you
def __str__(self):
return unicode(self).encode('utf-8')
def __unicode__(self):
return self.name
我的猜测是,print对要打印的对象obj
执行如下操作:
检查obj
是否为unicode
。如果是,则将其编码为sys.stdout.encoding
并打印
检查obj
是否为str
。如果是,则直接打印
如果obj
是其他内容,则调用str(obj)
并打印该内容
第一步。这就是为什么print obj.\uu str\uu()
在您的案例中有效
现在,str(obj)
所做的是:
调用对象
如果结果是一个str
,则返回它
如果结果是一个unicode
,则将其编码为“ascii”
,并返回该值
否则,有些东西几乎是无用的
调用obj.\uuuu str\uuuu()
直接跳过步骤2-3,这就是为什么编码没有失败
问题不是由print
的工作方式引起的,而是由str()
的工作方式引起的str()
忽略sys.stdout.encoding
。因为它不知道你想对结果字符串做什么,所以它使用的默认编码可以被认为是任意的ascii
是一个好或坏的选择
要防止此错误,请确保按照文档中的说明,从\uuu str\uuu()
返回str
。可用于Python 2.x的模式可能是:
class Foo():
def __unicode__(self):
return u'whatever'
def __str__(self):
return unicode(self).encode(sys.stdout.encoding)
(如果您确信除了打印到控制台之外不需要任何东西的str()
表示。)您正在运行的Python版本是什么?显示一个包含打印字符串示例的obj类的最小示例。您可能正在寻找obj.\uuuu unicode\uuuu()
?您使用的是哪一版本的Python?旁白:您可能不应该从对象外部调用\uuu函数。使用str(obj)
和repr(obj)
代替。从技术上讲,在Python(3.x)的最新版本中,这种区别已经不存在了。谢谢你,这是我想要的完美解释。这当然可以解释我的问题。现在,如果我真的希望有更多的控制台输出呢。什么是好的解决方案?我的方法是定义第二个参数,如下所示:\uuu str\uuu(self,encoding=sys.stdout.encoding)
。这似乎是一个好主意吗?@user1461135实际上没有一种情况下,您会将额外的参数传递到\uu str\uu()
,因为您不需要直接调用它。只要你想调用obj,我就使用unicode(obj).encode('yadda')
。\uu str\uuuu(encoding='yadda')
,它就不太可能让人惊讶。
class Foo():
def __unicode__(self):
return u'whatever'
def __str__(self):
return unicode(self).encode(sys.stdout.encoding)