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)