Python的字符串和unicode强制/魔术函数如何工作?

时间:2013-05-07 07:34:22

标签: python python-2.7 coercion

我正在使用Python版本:2.7.3。

在Python中,我们使用魔术方法__str____unicode__来定义strunicode在自定义类上的行为:

>>> class A(object):
  def __str__(self):
    print 'Casting A to str'
    return u'String'
  def __unicode__(self):
    print 'Casting A to unicode'
    return 'Unicode'


>>> a = A()
>>> str(a)
Casting A to str
'String'
>>> unicode(a)
Casting A to unicode
u'Unicode'

行为表明__str____unicode__的返回值被强制转换为strunicode,具体取决于运行的魔术方法。

但是,如果我们这样做:

>>> class B(object):
  def __str__(self):
    print 'Casting B to str'
    return A()
  def __unicode__(self):
    print 'Casting B to unicode'
    return A()


>>> b = B()
>>> str(b)
Casting B to str

Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    str(b)
TypeError: __str__ returned non-string (type A)
>>> unicode(b)
Casting B to unicode

Traceback (most recent call last):
  File "<pyshell#48>", line 1, in <module>
    unicode(b)
TypeError: coercing to Unicode: need string or buffer, A found

调用str.mro()unicode.mro()表示两者都是basestring的子类。但是,__unicode__还允许返回buffer个对象,这些对象直接继承自object,并且不会从basestring继承。

所以,我的问题是,strunicode被调用时实际发生了什么? __str____unicode__strunicode使用的返回值要求是什么?

1 个答案:

答案 0 :(得分:4)

  

但是,__unicode__也允许返回缓冲区对象   直接对象,不从basetring继承。

这不正确。 unicode()可以转换字符串或缓冲区。这是使用默认编码将传递的参数转换为unicode的“最佳尝试”(这就是为什么它说强制)。它将始终返回一个unicode对象。

  

所以,我的问题是,str和unicode实际发生了什么   叫什么名字? __str____unicode__的回报值要求是什么?   __str__用于str和unicode?

str()应返回对象的非正式,人性化的字符串表示。当有人在您的对象上使用__unicode__或者您的对象是print语句的一部分时,就会调用此方法。

unicode应始终返回 __str__对象。如果未定义此方法,则调用unicode(),然后将结果强制转换为unicode(通过将它们传递给__unicode__)。

在第二个示例中,您将返回无效对象,这就是您看到错误消息的原因。由于副作用,您的第一个示例似乎适用于{{1}},但它也没有正确编写。

文档的data model部分值得一读,以获取有关这些“魔术方法”的更多信息和详细信息。