回答:
__str__()
古いメソッドです-バイトを返します。__unicode__()
新しい優先メソッドです-文字を返します。名前はやや混乱しますが、2.xでは互換性の理由でそのまま使用されています。一般に、すべての文字列フォーマットをに入れ__unicode__()
、スタブ__str__()
メソッドを作成する必要があります。
def __str__(self):
return unicode(self).encode('utf-8')
3.0では、str
文字が含まれているため、同じメソッドの名前は__bytes__()
および__str__()
です。これらは期待どおりに動作します。
__unicode__
から実行するとどうなりstr(obj)
ますか?
unicode
NameError
Python 3でa を発生させます。2と3の両方で機能する単純なパターンですか?
future
パッケージはpython_2_unicode_compatible
Djangoを依存関係なしで提供します。
特定のクラスのマイクロ最適化文字列化について特に気にしない場合は__unicode__
、より一般的なため、常に実装するだけにします。そのような細かいパフォーマンスの問題(これは例外であり、規則では__str__
ありません)に関心がある場合、(文字列化された出力に非ASCII文字がないことを証明できる場合のみ)または両方(両方が可能である場合)を持っている可能性があります。助けて。
これらは確かな原則だと思いますが、実際にはそれを証明する努力をせずにASCII文字しか存在しないことは非常に一般的です(たとえば、文字列化された形式には数字、句読点、そしておそらく短いASCII名しかありません;-)。直接「ただ__str__
」のアプローチに直接進むことが非常に一般的である場合(ただし、私が一緒に作業したプログラミングチームがそれを回避するためにローカルガイドラインを提案した場合、これらの問題で誤りが発生しやすいため、提案に+1します。 「時期尚早な最適化はプログラミングにおけるすべての悪の根源です」;-)。
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))
次に出力例を示します(ここで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__
Python 2: __str __()のみを実装し、ユニコードを返します。
場合__unicode__()
省略している人の呼び出しunicode(o)
またはu"%s"%o
、Pythonのコールo.__str__()
と変換システムエンコーディングを使用してUnicodeに。(のドキュメントを__unicode__()
参照してください。)
反対は真実ではありません。実装しても実装し__unicode__()
ない__str__()
場合、誰かがstr(o)
orを呼び出すと"%s"%o
、Pythonが返されますrepr(o)
。
根拠
unicode
from を返すのはなぜでしょう__str__()
か?がユニコードを返す
場合__str__()
、Pythonは自動的str
にシステムエンコーディングを使用するように変換します。
メリットは何ですか?
①システムエンコーディングが何であるかを気にする必要がありません(つまり、locale.getpreferredencoeding(…)
)。個人的には面倒なだけでなく、システムが対処すべきことだと思います。②注意すると、コードがPython 3と相互互換になる可能性があり__str__()
ます。
呼び出された関数からユニコードを返すのは不正ではありません__str__()
か?
少し。ただし、すでに実行している可能性があります。あなたが持っている場合はfrom __future__ import unicode_literals
、ファイルの先頭に、あなたもそれを知らずにユニコードを返している可能性が高いと言えます。
Python 3はどうですか?
Python 3はを使用しません__unicode__()
。ただし、__str__()
Python 2またはPython 3のいずれかでユニコードを返すように実装すると、コードのその部分は相互互換性があります。
unicode(o)
実質的に違うものにしたい場合はどうなりstr()
ますか?
の両方を実装します__str__()
(おそらく戻るstr
)と__unicode__()
。これはまれだと思いますが、実質的に異なる出力が必要な場合があります(たとえば、":)"
forのような特殊文字のASCIIバージョンu"☺"
)。
一部の人がこの論争を呼ぶかもしれないことに気づきます。
__unicode__
特に2.と並べて定義されている場合、Python 2.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