Python __str__与__unicode__

Cor*_*ory 210 python string unicode conventions

有没有时,你应该实现一个python约定__str__()__unicode__().我已经看到类的覆盖__unicode__()频率高于__str__()它但看起来并不一致.当一个与另一个相比更好的时候是否有特定的规则?是否有必要/良好做法同时实施?

Joh*_*kin 254

__str__()是旧方法 - 它返回字节.__unicode__()是新的首选方法 - 它返回字符.名字有点令人困惑,但在2.x中,出于兼容性原因,我们坚持使用它们.通常,您应该将所有字符串格式设置为__unicode__(),并创建存根__str__()方法:

def __str__(self):
    return unicode(self).encode('utf-8')
Run Code Online (Sandbox Code Playgroud)

在3.0中,str包含字符,因此相同的方法被命名__bytes__()__str__().这些行为符合预期.

  • 实施其中只有一个是否有任何陷阱?当你只实现`__unicode__`然后执行`str(obj)`时会发生什么? (12认同)
  • `unicode`在Python 3上引发了一个`NameError`,是一个适用于2和3的简单模式? (9认同)
  • 你的意思是创建__unicode__和__str__方法或只是保持_(u"")中的字符串并创建__string__(没有unicode方法)? (2认同)
  • 这取决于。因为 python3 不使用 __unicode__ 而是使用 __str__ ;) for python 2 __unicode__ (2认同)

Ale*_*lli 23

如果我不特别关心给定类的微优化字符串化,我总是__unicode__只实现它,因为它更通用.当我关心这些微小的性能问题(这是例外,而不是规则),__str__只有(当我可以证明在字符串化输出中永远不会有非ASCII字符时)或两者(当两者都可能时),可能救命.

我认为这些是坚实的原则,但在实践中,知道除了ASCII字符之外什么也没有做任何努力来证明它(例如字符串形式只有数字,标点符号,也许是一个简短的ASCII名称;-),这是很常见的.如果直接转向"正义__str__"方法是很典型的(但是如果我合作的编程团队提出了一个避免这种情况的本地指南,那么我会在提案中获得+1,因为在这些问题上很容易出错"过早优化是编程中所有邪恶的根源";-).

  • 在python 2.6.2中,我最近被绊倒了,因为特定内置Exception子类的实例给出了str(e)和unicode(e)的不同结果.str(e)提供了用户友好的输出; unicode(e)给出了不同的,用户不友好的输出.这被认为是有缺陷的行为吗?该类是UnicodeDecodeError; 我没有预先说明它以避免混淆 - 与例外的unicode相关的事实并不特别相关. (2认同)

Aar*_*lla 13

随着世界变小,您遇到的任何字符串最终都可能包含Unicode.因此,对于任何新应用程序,您至少应该提供__unicode__().你是否也覆盖__str__()是一个品味问题.

  • 如果您正在编写 Python 3 代码,则定义 `__unicode__` 不会执行任何操作。 (4认同)

sag*_*age 7

如果您在Django中同时使用python2和python3,则建议使用python_2_unicode_compatible装饰器:

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

如前面对另一个答案的注释中所述,某些版本的future.utils也支持此装饰器。在我的系统上,我需要为python2安装一个更新的future模块,并为python3安装future。之后,这是一个功能示例:

#! /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))
Run Code Online (Sandbox Code Playgroud)

这是示例输出(其中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__
Run Code Online (Sandbox Code Playgroud)