是否有python约定,何时应该实现__str__()而不是__unicode__()。我已经看到类重写__unicode__()比__str__()更频繁,但它似乎不一致。是否存在特定的规则,以便更好地执行其中一个而不是另一个?两者都实现是必要的/好的做法吗?
当前回答
__str__()是旧的方法——它返回字节。__unicode__()是新的首选方法——它返回字符。这些名字有点混乱,但在2。X,我们因为兼容性的原因被困住了。通常,你应该把所有的字符串格式放在__unicode__()中,并创建一个存根__str__()方法:
def __str__(self):
return unicode(self).encode('utf-8')
在3.0中,str包含字符,因此相同的方法被命名为__bytes__()和__str__()。它们的行为与预期一致。
其他回答
__str__()是旧的方法——它返回字节。__unicode__()是新的首选方法——它返回字符。这些名字有点混乱,但在2。X,我们因为兼容性的原因被困住了。通常,你应该把所有的字符串格式放在__unicode__()中,并创建一个存根__str__()方法:
def __str__(self):
return unicode(self).encode('utf-8')
在3.0中,str包含字符,因此相同的方法被命名为__bytes__()和__str__()。它们的行为与预期一致。
随着世界越来越小,您遇到的任何字符串最终都可能包含Unicode。所以对于任何新的应用程序,你至少应该提供__unicode__()。是否也重写__str__()则只是个人喜好的问题。
Python 2:只实现__str__(),并返回unicode。
当__unicode__()被省略并且有人调用unicode(o)或u"%s"%o时,Python调用o.__str__()并使用系统编码转换为unicode。(请参阅__unicode__()的文档。)
反之则不然。如果你实现了__unicode__()而不是__str__(),那么当有人调用str(o)或“%s”%o时,Python会返回repr(o)。
基本原理
为什么从__str__()返回unicode ? 如果__str__()返回unicode, Python会自动使用系统编码将其转换为str。
有什么好处? ①它使你不必担心系统编码是什么(例如,locale.getpreferredencoeding(…))。就我个人而言,这不仅很麻烦,而且我认为这是系统应该解决的问题。如果你小心的话,你的代码可能会与python3交叉兼容,在python3中__str__()返回unicode。
从一个名为__str__()的函数返回一个unicode难道不是一种欺骗吗? 一点。然而,你可能已经在做了。如果你在你的文件顶部有from __future__ import unicode_literals,你很有可能在不知道的情况下返回一个unicode。
Python 3怎么样? Python 3没有使用__unicode__()。然而,如果你实现__str__(),使它返回Python 2或Python 3下的unicode,那么你的代码的这一部分将是交叉兼容的。
如果我想要unicode(o)从本质上不同于str()? 同时实现__str__()(可能返回str)和__unicode__()。我想这种情况很少见,但是您可能想要有实质上不同的输出(例如,特殊字符的ASCII版本,如“:)”表示u“☺”)。
我知道有些人可能会觉得这很有争议。
如果你在Django中同时使用python2和python3,我推荐使用python_2_unicode_compatible装饰器:
Django提供了一种简单的方法来定义在Python 2和3上工作的str()和unicode()方法:你必须定义一个str()方法来返回文本并应用python_2_unicode_compatible()装饰器。
正如前面对另一个答案的评论中提到的,future的一些版本。util也支持这个装饰器。在我的系统上,我需要为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))
以下是示例输出(其中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__
对于那些不熟悉__unicode__函数的人,有必要指出Python 2中围绕__unicode__函数的一些默认行为。X,特别是当与__str__一起定义时。
class A :
def __init__(self) :
self.x = 123
self.y = 23.3
#def __str__(self) :
# return "STR {} {}".format( self.x , self.y)
def __unicode__(self) :
return u"UNICODE {} {}".format( self.x , self.y)
a1 = A()
a2 = A()
print( "__repr__ checks")
print( a1 )
print( a2 )
print( "\n__str__ vs __unicode__ checks")
print( str( a1 ))
print( unicode(a1))
print( "{}".format( a1 ))
print( u"{}".format( a1 ))
产生以下控制台输出…
__repr__ checks
<__main__.A instance at 0x103f063f8>
<__main__.A instance at 0x103f06440>
__str__ vs __unicode__ checks
<__main__.A instance at 0x103f063f8>
UNICODE 123 23.3
<__main__.A instance at 0x103f063f8>
UNICODE 123 23.3
现在,当我取消注释__str__方法时
__repr__ checks
STR 123 23.3
STR 123 23.3
__str__ vs __unicode__ checks
STR 123 23.3
UNICODE 123 23.3
STR 123 23.3
UNICODE 123 23.3
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- Printf与std::字符串?
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if