打印obj和print obj .__ str __()之间的Python差异[至少用Unicode?]

jav*_*vex 9 python unicode

我被告知要调用print obj将调用obj.__str__()哪个将返回一个字符串以打印到控制台.现在我遇到了Unicode的问题,我无法打印任何非ascii字符.我得到了典型的"ascii超出范围"的东西.

在尝试以下工作时:

print obj.__str__()
print obj.__repr__()
Run Code Online (Sandbox Code Playgroud)

两个函数完全相同(__str__()只返回self.__repr__()).什么没有奏效:

print obj
Run Code Online (Sandbox Code Playgroud)

仅在使用ascii范围之外的字符时才会出现此问题.最终的解决方案是以下内容__str__():

return self.__repr__().encode(sys.stdout.encoding)
Run Code Online (Sandbox Code Playgroud)

现在它适用于所有部件.我现在的问题是:区别在哪里?为什么现在有用?如果没有任何效果我会得到,为什么现在这样.但为什么只有顶部工作,而不是底部.

操作系统是Windows 7 x64,带有默认的Windows命令提示符.此外,报告编码cp850.这是理解python的一般问题.我的问题已经解决了,但我并不是百分之百满意,主要是因为现在调用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
Run Code Online (Sandbox Code Playgroud)

删除最后一个obj,它的工作原理.保持它,它崩溃了

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
Run Code Online (Sandbox Code Playgroud)

mil*_*ose 4

obj我的猜测是 print 对于要打印的对象执行如下操作:

  1. 检查是否obj是一个unicode. 如果是,则将其编码sys.stdout.encoding并打印。
  2. 检查是否obj是一个str. 如果是,则直接打印。
  3. 如果obj有其他内容,则调用str(obj)并打印它。

第 1 步是为什么print obj.__str__()适用于您的情况。

现在,str(obj)所做的是:

  1. 称呼obj.__str__()
  2. 如果结果是 a str,则返回它
  3. 如果结果是 a unicode,则将其编码为"ascii"并返回
  4. 否则的话,大部分都是无用的东西。

直接调用obj.__str__()会跳过步骤 2-3,这就是您不会遇到编码失败的原因。

问题不是由print工作方式引起的,而是由str()工作方式引起的。str()忽略sys.stdout.encoding. 由于它不知道您想对结果字符串做什么,因此它使用的默认编码可以被认为是任意的;ascii是一个好还是坏的选择。

为了防止出现此错误,请确保按照文档的指示返回strfrom 。__str__()可用于 Python 2.x 的模式可能是:

class Foo():
    def __unicode__(self):
        return u'whatever'
    def __str__(self):
        return unicode(self).encode(sys.stdout.encoding)
Run Code Online (Sandbox Code Playgroud)

str()(如果您确定除了打印到控制台之外不需要任何表示。)