Python __str__与__unicode__

有什么时候应该实现__str__()__unicode__()的Python约定。 我看到__unicode__() __str__() __unicode__()更频繁地覆盖__unicode__() __str__()但它看起来并不一致。 实施一个和另一个比较好时,是否有特定的规则? 是否有必要/好的做法来执行这两个?

__str__()是旧的方法 – 它返回字节。 __unicode__()是新的首选方法 – 它返回字符。 名字有点令人困惑,但在2.x中,出于兼容性原因,我们仍然坚持使用它们。 一般来说,你应该把所有的string格式放在__unicode__() ,并创build一个存根__str__()方法:

 def __str__(self): return unicode(self).encode('utf-8') 

在3.0中, str包含字符,所以相同的方法被命名为__bytes__()__str__() 。 这些行为如预期。

如果我不特别关心给定类的微优化string化,我总是只实现__unicode__ ,因为它更一般。 当我关心如此微小的性能问题(这是例外,而不是规则)时,只有__str__ (当我可以certificate在string输出中永远不会有非ASCII字符)或者两者都有(当两者都是可能的时候),可能会有帮助

这些我认为是可靠的原则,但是在实践中,知道只有ASCII字符而没有做任何事情来certificate它(例如,stringforms只有数字,标点符号和一个简短的ASCII名称)在这种情况下,直接采用“just __str__ ”方法是非常典型的做法(但是如果我与之合作的编程团队提出了一个避免这个问题的本地指导方针,那么对于这个提议我就会是+1,因为在这些问题上很容易出错而“过早优化是编程中所有邪恶的根源”—)。

随着世界越来越小,有可能你遇到的任何string最终都会包含Unicode。 所以对于任何新的应用程序,你至less应该提供__unicode__() 。 无论你是否还要覆盖__str__()都只是一个口味问题。

如果您在Django中使用python2和python3,我推荐使用python_2_unicode_compatible装饰器:

Django提供了一种简单的方法来定义在Python 2和3上工作的str ()和unicode ()方法:您必须定义一个返回文本的str ()方法并应用python_2_unicode_compatible()修饰器。

正如前面对另一个答案的评论所指出的,future.utils的一些版本也支持这个装饰器。 在我的系统上,我需要为python2安装一个更新的未来模块,并为python3安装未来版本。 之后,这里是一个function的例子:

 #! /usr/bin/env python from future.utils import python_2_unicode_compatible from sys import version_info @python_2_unicode_compatible class SomeClass(): def __str__(self): return "Called __str__" if __name__ == "__main__": some_inst = SomeClass() print(some_inst) if (version_info > (3,0)): print("Python 3 does not support unicode()") else: print(unicode(some_inst)) 

以下是示例输出(其中venv2 / venv3是virtualenv实例):

 ~/tmp$ ./venv3/bin/python3 demo_python_2_unicode_compatible.py Called __str__ Python 3 does not support unicode() ~/tmp$ ./venv2/bin/python2 demo_python_2_unicode_compatible.py Called __str__ Called __str__