web-dev-qa-db-ja.com

Python __str__対__unicode__

__str__()__unicode__()を実装すべきときのためのpython規約があります。クラスは__unicode__()よりも頻繁に__str__()をオーバーライドしますが、一貫性がないようです。どちらか一方を実装する方が良い場合、特定のルールはありますか?両方を実装する必要がありますか?

209
Cory

__str__()は古いメソッドで、バイトを返します。 __unicode__()は、新しく推奨されるメソッドです。文字を返します。名前は少しわかりにくいですが、2.xでは互換性の理由からそれらに固執しています。通常、すべての文字列フォーマットを__unicode__()に入れ、スタブ__str__()メソッドを作成する必要があります。

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

3.0では、strに文字が含まれているため、同じメソッドの名前は__bytes__()および__str__()です。これらは期待どおりに動作します。

252
John Millikin

特定のクラスの文字列の最適化を特に気にしない場合は、__unicode__のみを実装します。これはより一般的です。 __str__のみ(文字列化された出力に非ASCII文字がないことを証明できる場合)または両方(両方の場合)可能)、役立つかもしれません。

これらは確固たる原理であると思いますが、実際には、それを証明する努力をせずにASCII文字しか存在しないことがよく知られています(たとえば、文字列形式には数字、句読点、そしておそらく短いASCII name ;-)この場合、「ちょうど__str__」アプローチに直接進むのが非常に一般的です(ただし、一緒に作業したプログラミングチームがそれを避けるためにローカルガイドラインを提案した場合、 dこれらの問題に誤りを犯しやすく、「早すぎる最適化がプログラミングのすべての悪の根源である」ため、提案に対して+1する必要があります;-)。

23
Alex Martelli

世界が小さくなっているため、遭遇する文字列にはいずれユニコードが含まれる可能性があります。したがって、新しいアプリの場合は、少なくとも__unicode__()を指定する必要があります。 __str__()もオーバーライドするかどうかは、好みの問題です。

13
Aaron Digulla

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__
6
sage

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バージョン)。

この論争の的になる人もいると思います。

1
Alex Quinn

特に__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
0
jxramos