- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在为打印和 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)
因此,当打印 unicode 字符串时,调用和打印的不是 __repr__()
函数。
但是当打印对象时 __str__()
或 __repr__()
(如果 __str__
未实现)被调用,而不是 __unicode__()
。两者都不能返回 unicode 字符串。
但为什么?为什么如果 __repr__()
或 __str__()
返回一个 unicode 字符串,它的行为不应该与我们打印 unicode 字符串时的行为相同吗?我换句话说:为什么 print D()
不同于 print D().__str__()
我错过了什么吗?
这些示例还表明,如果要打印用 unicode 字符串表示的对象,则必须将其编码为对象字符串(str 类型)。但是为了 pretty-print (避免“├®”),它依赖于 sys.stdout
编码。
那么,我是否必须为每个 __str__
或 __repr__
方法添加 u"é".encode(sys.stdout.encoding)
?或者返回 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")
谢谢!
最佳答案
Python 对给定的函数和方法没有许多语义类型约束,但它有一些,这是其中之一:__str__
(在 Python 2.* 中)必须返回一个字节字符串。像往常一样,如果在需要字节字符串的地方找到了一个 unicode 对象,则应用当前默认编码(通常是 'ascii'
)来尝试从有问题的 unicode 对象生成所需的字节字符串.
对于这个操作,任何给定文件对象的编码(如果有的话)是无关紧要的,因为从 __str__
返回的内容可能即将被打印,或者可能会被完全不同的和不相关的治疗。您调用 __str__
的目的与调用本身及其结果无关;通常,Python 在确定操作的语义时不会考虑操作的“ future 上下文”(操作完成后您将如何处理结果)。
那是因为 Python 并不总是知道您 future 的意图,它会尽量减少惊喜。 打印 str(x)
和 s = str(x); print s
(一口气与两口气执行的相同操作),尤其必须具有相同的效果;如果是第二种情况,如果 str(x)
不能有效地产生字节串(即,例如,x.__str__()
不能), 因此在其他情况下也应该出现异常。
print
本身(我相信从 2.4 开始),当出现一个 unicode 对象时,会考虑目标流的 .encoding
属性(如果有的话)(默认情况下 sys.stdout
);其他操作,尚未连接到任何给定的目标流,不会 - 而 str(x)
(即 x.__str__()
)就是这样的操作。
希望这有助于说明让您烦恼的行为的原因...
编辑:OP 现在澄清了“我的主要问题是使一个类“可打印”,即 print 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))
也就是说,这种方法侧重于 __unicode__
作为类实例格式化自身的主要方式——但是因为(在 Python 2 中)print
调用 __str__
相反,它有一个委托(delegate)给 __unicode__
在编码方面它可以做到最好。并不完美,但是 Python 2 的 print
语句无论如何都远非完美;-)。
__repr__
就其本身而言,必须努力明确,即不以冒风险为代价“看起来不错”歧义(理想情况下,如果可行,它应该返回一个字节字符串,如果将其传递给 eval
,将使实例等于当前实例......这远非总是可行,但没有歧义是 __str__
和 __repr__
之间区别的绝对核心,我强烈建议尊重这种区别!)。
关于python - 打印对象和 unicode,背后是什么?好的指导方针是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3557095/
如何将可为 null 的 guid (guid?) 转换为 guid?我的目的是将可为空的 Guid 列表转换为 Guid 列表。 最佳答案 使用??运算符: public static class
我正在尝试根据 jaro 距离给出的相似性对一组字符串进行聚类。我正在用 python 中的 JellyFish 计算它。我一直在努力弄清楚如何对数据进行聚类。我不是集群方面的专家,这是我第一次尝试弄
我正在寻找的是一种方法,它允许我在用户的浏览器中下载图像以备后用。图像将在鼠标悬停(悬停)事件上激活。问题是我不想只在用户悬停时才下载图像,因为它会产生不好的效果。它必须在网站加载时下载。 有什么建议
Closed. This question needs to be more focused。它当前不接受答案。
我有以下代码: SELECT * FROM ( SELECT p.ProductID, pc.Name, ISNULL(p.Color, 'Unco
再一次,我有一个关于 jQuery 的问题,但我正在尽我最大的努力学习,但有时教程并没有给我我需要的一切。 我正在尝试使一组选项卡起作用,但是,似乎没有任何效果.. 这是我正在使用的代码: HTML:
Guidance bootstrap validator 不适用于 nav nav-tabs help me 我创建了一个分为 4 个选项卡的表单,并将 Bootstrap 验证器添加到表单中以测试输
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求提供代码的问题必须表现出对所解决问题的最低限度理解。包括尝试过的解决方案、为什么它们不起作用,以及
这个问题不太可能帮助任何 future 的访问者;它只与一个小的地理区域、一个特定的时间点或一个非常狭窄的情况有关,这些情况并不普遍适用于互联网的全局受众。为了帮助使这个问题更广泛地适用,visit
我正在尝试使用 Akka Futures 读取多个文件并将每一行传递给可调用对象。我的可调用对象是特定文件的解析器。所以 people.txt 可能会填充 Person 类型的对象。每行可以包含超过
我正在寻求提高我的 javascript 的标准,因为我正在超越简单的 AJAX 形式,转向更丰富的交互,而且它很快就会失控。 关于如何编写正确的 javascript 的资源很多,很多最好的都来自
我正在导入一个包含多行的 Excel 文件。有些列是日期,我必须这样读取它们,但 Apache poi 无法正确读取单元格的格式。事实上,日期必须是 dd/MM/YYYY,但是当我有 04/13/20
我试图让爬虫在连续 3 次尝试后每次都找不到相关页面时“中止”搜索某个子域。提取页面的标题和文本后,我开始寻找正确的页面以提交到我的 solr 集合。 (我不想添加与此查询不匹配的页面) public
我计划使用 Python 制作一个桌面应用程序,以学习一些桌面概念。我打算使用 GTK 还是 Qt,我还没决定使用哪一个。 事实是:我想创建一个可以从命令行调用并使用 GUI 的应用程序。因此它对于
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
我正在将一个低级 C 库转换为 Delphi。 我找到了很多类型转换。我认为这在 C World 中很正常。我想我把它们扔掉是安全的。整数仅在此处为 32 位。你怎么看? 如果我将它转换为对象等,OO
我已经能够为我的 Sprite 应用平滑的动画并使用加速度计控制它。我的 Sprite 固定沿着 x 轴左右移动。 从这里开始,我需要弄清楚如何为 Sprite 创建一条垂直的无限波浪线以尝试追踪。我
我使用的是 Ubuntu,如何指示 pip 使用 Python3 安装而不是 Python2.6? 2.6 是 Ubuntu 上的默认安装。我无法升级它,因为它会破坏 Ubuntu。 最佳答案 任何单
我可以使用 cs50 中的一些帮助来解决此问题。每当我的代码遇到 while 循环时,fread 函数就会返回 0。我似乎无法理解为什么会发生这种情况。即使在我遇到这个问题之前,我的代码也没有按照我的
我已经阅读了很多关于该主题的文章(包括 scrapy 文档),但出于某种原因我无法登录到 vBulletin 网站。让我澄清一下,我不是开发人员,我对编程/抓取的知识非常基础,所以如果有人决定提供帮助
我是一名优秀的程序员,十分优秀!