__str__()
対__unicode__()
を実装すべきときのためのpython規約があります。クラスは__unicode__()
よりも頻繁に__str__()
をオーバーライドしますが、一貫性がないようです。どちらか一方を実装する方が良い場合、特定のルールはありますか?両方を実装する必要がありますか?
__str__()
は古いメソッドで、バイトを返します。 __unicode__()
は、新しく推奨されるメソッドです。文字を返します。名前は少しわかりにくいですが、2.xでは互換性の理由からそれらに固執しています。通常、すべての文字列フォーマットを__unicode__()
に入れ、スタブ__str__()
メソッドを作成する必要があります。
def __str__(self):
return unicode(self).encode('utf-8')
3.0では、str
に文字が含まれているため、同じメソッドの名前は__bytes__()
および__str__()
です。これらは期待どおりに動作します。
特定のクラスの文字列の最適化を特に気にしない場合は、__unicode__
のみを実装します。これはより一般的です。 __str__
のみ(文字列化された出力に非ASCII文字がないことを証明できる場合)または両方(両方の場合)可能)、役立つかもしれません。
これらは確固たる原理であると思いますが、実際には、それを証明する努力をせずにASCII文字しか存在しないことがよく知られています(たとえば、文字列形式には数字、句読点、そしておそらく短いASCII name ;-)この場合、「ちょうど__str__
」アプローチに直接進むのが非常に一般的です(ただし、一緒に作業したプログラミングチームがそれを避けるためにローカルガイドラインを提案した場合、 dこれらの問題に誤りを犯しやすく、「早すぎる最適化がプログラミングのすべての悪の根源である」ため、提案に対して+1する必要があります;-)。
世界が小さくなっているため、遭遇する文字列にはいずれユニコードが含まれる可能性があります。したがって、新しいアプリの場合は、少なくとも__unicode__()
を指定する必要があります。 __str__()
もオーバーライドするかどうかは、好みの問題です。
Djangoでpython2とpython3の両方で作業している場合、python_2_unicode_compatibleデコレータをお勧めします。
Djangoはstr()およびunicode()を定義する簡単な方法を提供しますPython 2および3で機能するメソッド:テキストを返し、python_2_unicode_compatible()を適用するために、str()メソッドを定義する必要がありますデコレータ。
別の回答に対する以前のコメントで述べたように、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 __== "__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__()
が省略され、誰かがunicode(o)
またはu"%s"%o
を呼び出すと、Pythonはo.__str__()
を呼び出し、システムエンコーディングを使用してUnicodeに変換します。 ( __unicode__()
のドキュメント を参照してください。)
その反対は真実ではありません。 __unicode__()
を実装し、__str__()
を実装しない場合、誰かがstr(o)
または"%s"%o
を呼び出すと、Pythonはrepr(o)
を返します。
根拠
__str__()
からunicode
を返すのはなぜ機能するのですか?__str__()
がユニコードを返す場合、Pythonはシステムエンコーディングを使用して自動的にstr
に変換します。
利点は何ですか?
①システムエンコーディングが何であるかを心配する必要がなくなります(つまり、locale.getpreferredencoeding(…)
)。個人的には面倒なだけでなく、とにかくシステムが面倒を見る必要があると思います。 ②注意を払えば、コードはPython 3と相互互換性があり、__str__()
はUnicodeを返します。
__str__()
?と呼ばれる関数からユニコードを返すことは欺cept的ではありませんか?
少し。ただし、すでにそれを行っている可能性があります。ファイルの先頭にfrom __future__ import unicode_literals
がある場合、知らなくてもUnicodeを返す可能性が高くなります。
Python 3はどうですか?
Python 3は__unicode__()
を使用しません。ただし、Python 2またはPython 3のいずれかでUnicodeを返すように__str__()
を実装する場合、コードのその部分は相互互換性があります。
unicode(o)
をstr()
と実質的に異なるものにしたい場合はどうすればいいですか?__str__()
(おそらくstr
を返す)と__unicode__()
の両方を実装します。これはまれだと思いますが、実質的に異なる出力が必要になる場合があります(例:":)"
for u"☺"
などの特殊文字のASCIIバージョン)。
この論争の的になる人もいると思います。
特に__unicode__
と並んで定義されている場合は、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