__str__と__repr__の違いは?


回答:


2724

アレックスはうまくまとめましたが、驚いたことに、簡潔すぎました。

まず、アレックスの投稿の要点を繰り返します。

  • デフォルトの実装は役に立たない(そうでないものを考えるのは難しいが、そうです)
  • __repr__ 目標は明確にすることです
  • __str__ 目標は読みやすくすることです
  • コンテナ__str__は、含まれているオブジェクトを使用します__repr__

デフォルトの実装は役に立たない

Pythonのデフォルトはかなり役立つ傾向があるため、これはほとんど驚きです。ただし、この場合、次の__repr__ように動作するデフォルトを持っています。

return "%s(%r)" % (self.__class__, self.__dict__)

危険すぎる(たとえば、オブジェクトが相互に参照している場合、無限再帰に入るのは簡単すぎる)。したがって、Pythonは対処します。trueであるデフォルトが1つあることに注意してください。__repr__が定義されていて定義されて__str__いない場合、オブジェクトはのように動作します__str__=__repr__

つまり、簡単に言うと、実装するほとんどすべてのオブジェクトには__repr__、オブジェクトを理解するために使用できる関数が必要です。実装__str__はオプションです。「きれいな印刷」機能(たとえば、レポートジェネレーターで使用される)が必要な場合は、実装してください。

の目標は__repr__明確にすることです

私はすぐに出て言ってみましょう—私はデバッガを信じていません。私はデバッガの使い方を本当に知りませんし、真剣にデバッガを使ったことがありません。さらに、デバッガーの大きな障害はそれらの基本的な性質であると私は信じています。私がデバッグするほとんどの障害は、はるか昔に遠く離れた銀河で発生しました。つまり、私は宗教的な熱意をもって伐採を信じています。ロギングは、きちんとしたファイアアンドフォーゲットサーバーシステムの生命線です。Pythonを使用すると、ログを簡単に作成できます。プロジェクト固有のラッパーを使用すると、必要なのは

log(INFO, "I am in the weird function and a is", a, "and b is", b, "but I got a null C — using default", default_c)

ただし、最後の手順を実行する必要があります。実装するすべてのオブジェクトに有効なreprがあることを確認して、そのようなコードが機能するようにします。これが「評価」の事柄が浮かび上がる理由です。十分な情報があればeval(repr(c))==c、それは知っていることのすべてを知っていることを意味しますc。それが十分に簡単な場合は、少なくともあいまいな方法で実行してください。そうでない場合は、cとにかく十分な情報があることを確認してください。私は通常、evalのような形式を使用します"MyClass(this=%r,that=%r)" % (self.this,self.that)。これは、実際にMyClassを構築できること、またはそれらが正しいコンストラクター引数であることを意味するわけではありませんが、「これは、このインスタンスについて知る必要があるすべてのものです」と表現するのに便利です。

注:%r上記ではなくを使用しました%s。あなたは常に内部でrepr()[または%r同等にフォーマット文字を使用したい]__repr__実装、またはreprの目標を打ち負かしている。あなたが差別化できるようにしたいMyClass(3)としMyClass("3")ます。

の目標 __str__は、読みやすくすることです

具体的には、明確にすることを意図したものではありません。 str(3)==str("3")。同様に、IP抽象化を実装する場合、そのstrが192.168.1.1のように見えることで十分です。日付/時刻の抽象化を実装する場合、strは「2010/4/12 15:35:22」などにすることができます。目標は、プログラマではなくユーザーがそれを読みたいように表現することです。不要な数字を切り捨て、他のクラスのふりをします—読みやすさをサポートしている限り、それは改善です。

コンテナ__str__は、含まれているオブジェクトを使用します__repr__

これは意外ですね。それは少し__str__ですが、それを使用した場合、どれほど読みやすいでしょうか?

[moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

それほどではありません。具体的には、コンテナ内の文字列は、文字列表現を乱すことが非常に簡単であることがわかります。あいまいさに直面して、Pythonは推測する誘惑に抵抗します。リストを印刷するときに上記の動作が必要な場合は、

print "[" + ", ".join(l) + "]"

(おそらく、辞書について何をすべきかを理解することもできます。

概要

実装__repr__するクラスに実装します。これは第二の性質であるべきです。__str__読みやすさの面でエラーのある文字列バージョンがあると便利な場合に実装します。


154
デバッグする方法ではないというあなたの意見に完全に同意しないでください。開発にはデバッガー(および/またはロギング)を使用し、実稼働にはロギングを使用します。デバッガーを使用すると、問題が発生したときに問題が発生したすべての状況を確認できます。全体像を見ることができます。すべてをログに記録しない限り、それを取得することはできません。さらに、すべてをログに記録する場合は、大量のデータを調べて必要なものを取得する必要があります。
サミュエル

21
すばらしい答えです(デバッガーを使用しないことを除いて)。Python 3のstrunicodeに関するこの他のQ&Aへのリンクを追加したいと思います。これは、切り替えを行った人々の議論に関連する可能性があります。
ThatAintWorking 2015年

11
plus1 for debuggersは役に立たず、10セントほどの価値はありません。代わりに、ログのスループットを上げてください。そして、はい、これはよく書かれた投稿でした。結局__repr__、デバッグに必要なことがわかりました。ご協力ありがとうございました。
personal_cloud

7
あなたのデバッガは愚かですが、私は%rを学びました、それはとにかく投票する価値があります
Mickey Perlstein

7
デバッガーとデバッガーなし:そのような根強い意見を得ないでください。一部のアプリケーションでは、デバッグが現実的ではありません。通常、リアルタイムが関係している場合や、アクセスがほとんどないかコンソールがないプラットフォームでコードがリモートでのみ実行される場合です。他のほとんどの場合、調査のために例外で停止したり、ブレークポイントを設定したりする方がはるかに速くなります。何千行ものロギングを実行する必要がないためです(ディスクが乱雑になり、アプリケーションの速度が低下します)。最後に、たとえば組み込みデバイスなどでは、常にログを記録できるとは限りません。デバッガもあなたの友達です。
RedGlyph

523

私の経験則: __repr__開発者__str__向け、顧客向けです。


2
obj = uuid.uuid1()の場合、obj .__ str __()は "2d7fc7f0-7706-11e9-94ae-0242ac110002"であり、obj .__ repr __()は "UUID( '2d7fc7f0-7706-11e9-94ae-0242ac110002 ') "。開発者は(値+オリジン)を必要としますが、顧客は値を必要とし、彼らはそれをどのように取得したかを気にしません。
Naren Yellavula、

1
ここで、顧客は必ずしもエンドユーザーを意味するとは限りません。オブジェクトのクライアントまたはユーザーです。したがって、SDKの場合、SDK開発者は__str__、通常の開発者が読み取り可能なオブジェクトを使用するようにします。一方、__repr__SDK開発者自身のためです。
Shiplu Mokaddim

398

特にそうでないことを確認するために特別に行動しない限り、ほとんどのクラスには、次のいずれについても役立つ結果がありません。

>>> class Sic(object): pass
... 
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>> 

ご覧のとおり、違いはなく、クラスとオブジェクト以外の情報もありませんid。2つのうち1つだけをオーバーライドする場合...:

>>> class Sic(object): 
...   def __repr__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
...   def __str__(object): return 'foo'
... 
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>> 

ご覧__repr__のとおり、をオーバーライドすると、それもに使用されますが、その__str__逆はありません。

その他の重要な一口は知っている:__str__ビルトインにコンテナの用途に__repr__、NOT __str__、アイテムのためにそれが含まれています。そして、典型的なドキュメントで見つかった主題に関する単語にもかかわらず、__repr__オブジェクトの文字列をeval同等のオブジェクトを構築するために使用できるようにすることをません(それは非常に難しいです、そして関連するモジュールが実際にどのようにインポートされたかを知らないと、実際にそれを作りますフラットアウト不可能)。

したがって、私のアドバイス:の戻り値をへの入力として受け入れられるようにするというあいまいな達成不可能な目標に干渉する場合でも__str__、人間が可読かつ合理的に可能な__repr__限り明確にすることに集中してください。__repr____eval__


34
単体テストではeval(repr(foo))、がと等しいオブジェクトに評価されることを常に確認しますfoo。モジュールのインポート方法がわからないので、テストケース以外では機能しませんが、これにより、少なくとも一部の予測可能なコンテキストで機能することが保証されます。これは、結果が__repr__十分に明確かどうかを評価する良い方法だと思います。単体テストでこれを行う__repr__と、クラスの変更を確実に追跡できます。
スティーブンT.スナイダー

4
私は常にeval(repr(spam)) == spam(少なくとも正しいコンテキストでは)またはeval(repr(spam))を発生させることを常に確認しようとしSyntaxErrorます。そうすれば混乱を避けることができます。(そして、それはだ、ほとんど組み込みコマンドのために真とSTDLIBのほとんどを除いて、例えば、再帰的なリスト、a=[]; a.append(a); print(eval(repr(a)))あなたが与える[[Ellipses]]...)もちろん私は実際にすることをしない使用 eval(repr(spam))ユニットテストでの健全性チェックなどを除き、...しかし、私は、時にはコピー&ペーストインタラクティブセッションに。repr(spam)
abarnert 2014

コンテナ(リスト、タプル)__str__ではなく、各要素に使用しないのはなぜ __repr__ですか?__str__私はオブジェクトにリーダブルを実装し、それがリストの一部である場合、__repr__代わりに醜いものを見るので、私には明白に間違っているようです。
SuperGeo 2018年

eval(repr(x))組み込み型でも失敗するという事実に関連する厄介なバグに遭遇しただけで、class A(str, Enum): X = 'x'SyntaxErrorが発生しeval(repr(A.X))ます。悲しいですが、理解できます。ところで、eval(str(A.X))実際には機能しますが、もちろんclass A範囲内にある場合に限られます。したがって、おそらくあまり役​​に立ちません。
最大

@SuperGeo他の回答はこれをカバーしています:!=のため、コンテナstrは要素を使用します。repr[1, 2, 3]["1", "2, 3"]
mtraceur

163

__repr__:pythonオブジェクトの表現は通常evalでそのオブジェクトに変換されます

__str__:あなたがテキスト形式のオブジェクトだと思うものは何でも

例えば

>>> s="""w'o"w"""
>>> repr(s)
'\'w\\\'o"w\''
>>> str(s)
'w\'o"w'
>>> eval(str(s))==s
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    w'o"w
       ^
SyntaxError: EOL while scanning single-quoted string
>>> eval(repr(s))==s
True

151

要するに、の目標__repr__は、明確に__str__することと読みやすくすることです。

ここに良い例があります:

>>> import datetime
>>> today = datetime.datetime.now()
>>> str(today)
'2012-03-14 09:21:58.130922'
>>> repr(today)
'datetime.datetime(2012, 3, 14, 9, 21, 58, 130922)'

reprについては、このドキュメントをお読みください。

repr(object)

オブジェクトの印刷可能な表現を含む文字列を返します。これは、変換(逆引用符)によって得られる値と同じです。この操作に通常の関数としてアクセスできると便利な場合があります。多くのタイプの場合、この関数は、に渡されたときに同じ値を持つオブジェクトを生成する文字列を返そうとしますeval()。それ以外の場合、表現は、オブジェクトのタイプの名前と追加情報を含む山括弧で囲まれた文字列です。多くの場合、オブジェクトの名前とアドレスが含まれます。クラスは、__repr__()メソッドを定義することにより、この関数がインスタンスに対して返すものを制御できます。

strのドキュメントは次のとおりです。

str(object='')

オブジェクトの適切に印刷可能な表現を含む文字列を返します。文字列の場合、これは文字列自体を返します。との違いrepr(object)は、str(object)常に受け入れ可能な文字列を返そうとするわけではないことeval()です。その目的は、印刷可能な文字列を返すことです。引数を指定しない場合、空の文字列を返します''


1
ここで印刷可能な文字列の意味は何ですか?説明して頂けますか?
Vicrobot、2018

115

違いは何である__str____repr__Pythonでは?

__str__ (「dunder(double-underscore)string」と読みます)そして __repr__として読み取られます(「dunder-repper」(「表現」のために読み取られます))は、どちらもオブジェクトの状態に基づいて文字列を返す特別なメソッドです。

__repr____str__がない場合のバックアップ動作を提供します。

したがって、最初に、__repr__たとえば、使用するevalか、Pythonシェルで文字ごとに入力することによって、返される文字列から同等のオブジェクトをインスタンス化できるようにするを記述します。

後でいつでも、__str__それが必要だと思われるときに、ユーザーが読み取れるインスタンスの文字列表現を記述できます。

__str__

あなたは、オブジェクトを印刷、またはにそれを渡した場合formatstr.formatまたはstr、ならば、__str__メソッドが定義され、そのメソッドが呼び出されます、そうでない場合は、__repr__使用されます。

__repr__

この__repr__メソッドは組み込み関数によって呼び出されrepr、オブジェクトを返す式を評価するときにPythonシェルにエコーされます。

のバックアップを提供するため__str__、1つしか記述できない場合は、__repr__

ここに組み込みのヘルプがありreprます:

repr(...)
    repr(object) -> string

    Return the canonical string representation of the object.
    For most object types, eval(repr(object)) == object.

つまり、ほとんどのオブジェクトで、印刷されたものを入力すると reprすると、同等のオブジェクトを作成できるはずです。しかし、これはデフォルトの実装ではありません。

のデフォルト実装 __repr__

デフォルトのオブジェクト__repr__は(C Python source)のようなものです:

def __repr__(self):
    return '<{0}.{1} object at {2}>'.format(
      self.__module__, type(self).__name__, hex(id(self)))

つまり、デフォルトでは、オブジェクトが存在するモジュール、クラス名、およびメモリ内のその場所の16進表現を出力します。たとえば、次のようになります。

<__main__.Foo object at 0x7f80665abdd0>

この情報はあまり役に立ちませんが、特定のインスタンスの正規表現を正確に作成する方法を導出する方法はありません。少なくとも、メモリ内でそれを一意に識別する方法を教えて、何もないよりはましです。

どの__repr__ように役立ちますか?

Pythonシェルとdatetimeオブジェクトを使用して、それがいかに便利かを見てみましょう。最初にdatetimeモジュールをインポートする必要があります:

import datetime

datetime.nowシェルで呼び出すと、同等の日時オブジェクトを再作成するために必要なものがすべて表示されます。これはdatetimeによって作成されます__repr__

>>> datetime.datetime.now()
datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)

日時オブジェクトを出力すると、人間が読める形式(実際はISO)で表示されます。これは、datetimeによって実装され__str__ます。

>>> print(datetime.datetime.now())
2015-01-24 20:05:44.977951

__repr__出力からコピーアンドペーストして変数に割り当てなかったために失ったオブジェクトを再作成し、それを印刷するのは簡単なことです。それを他のオブジェクトと同じ人間が読める出力で取得します。

>>> the_past = datetime.datetime(2015, 1, 24, 20, 5, 36, 491180)
>>> print(the_past)
2015-01-24 20:05:36.491180

それらをどのように実装しますか?

開発中は、可能であれば、オブジェクトを同じ状態で再現できるようにする必要があります。たとえば、これはdatetimeオブジェクトの定義方法です__repr__Pythonソース)。そのようなオブジェクトを再現するために必要なすべての属性のため、これはかなり複雑です。

def __repr__(self):
    """Convert to formal string, for repr()."""
    L = [self._year, self._month, self._day,  # These are never zero
         self._hour, self._minute, self._second, self._microsecond]
    if L[-1] == 0:
        del L[-1]
    if L[-1] == 0:
        del L[-1]
    s = "%s.%s(%s)" % (self.__class__.__module__,
                       self.__class__.__qualname__,
                       ", ".join(map(str, L)))
    if self._tzinfo is not None:
        assert s[-1:] == ")"
        s = s[:-1] + ", tzinfo=%r" % self._tzinfo + ")"
    if self._fold:
        assert s[-1:] == ")"
        s = s[:-1] + ", fold=1)"
    return s

オブジェクトをより人間が読める形式にしたい場合は、__str__次に実装できます。datetimeオブジェクト(Pythonソース)の実装方法は__str__次のとおりです。ISO形式で表示する関数がすでにあるため、簡単に実装できます。

def __str__(self):
    "Convert to string, for str()."
    return self.isoformat(sep=' ')

セット__repr__ = __str__

これは、セッティングを提案するここでの別の答えの批評です__repr__ = __str__

設定__repr__ = __str__はばかげている- __repr__のフォールバックで__str__あり、__repr__開発者がデバッグで使用するために作成されたは、を作成する前に作成する必要があります__str__

__str__オブジェクトのテキスト表現が必要な場合にのみ必要です。

結論

__repr__開発者が他の開発者と一緒に使用するときに再現可能な例を使用できるように、作成したオブジェクトを定義します。__str__人間が読める形式の文字列表現が必要な場合を定義します。


それは次のようなものではないtype(obj).__qualname__でしょうか?
ソロモンUcko 2018

@SolomonUckoはい、Python 3ではそうです。これが実装されているソースコードを探していました。一緒に入手したら、その情報で回答を更新します。
アーロンホール

33

ハンス・ペッター・ラングタンゲンの著書「計算科学のためのPythonスクリプト」の358ページには、

  • __repr__オブジェクトの完全な文字列表現を目指します。
  • これ__str__は、印刷用の素敵な文字列を返すことです。

だから、私はそれらを

  • repr =再現
  • str =文字列(表現)

これは私がpythonを学習するときに作った誤解ですが、ユーザーの観点からは。

次のように、小さいながらも良い例が同じページに示されています。

In [38]: str('s')
Out[38]: 's'

In [39]: repr('s')
Out[39]: "'s'"

In [40]: eval(str('s'))
Traceback (most recent call last):

  File "<ipython-input-40-abd46c0c43e7>", line 1, in <module>
    eval(str('s'))

  File "<string>", line 1, in <module>

NameError: name 's' is not defined


In [41]: eval(repr('s'))
Out[41]: 's'

それはページです。#351。
jiten 2018

4
repr再生と呼ぶのは誤解を招くようなものです。それを代表するものと考えるのが良いでしょう。
NelsonGon

31

与えられたすべての回答とは別に、いくつかのポイントを追加したいと思います:-

1)__repr__()インタラクティブなPythonコンソールでオブジェクトの名前を入力してEnterキーを押すと呼び出されます。

2)__str__()printステートメントでオブジェクトを使用すると呼び出されます。

3)__str__不足している場合は、印刷とstr()呼び出しを使用するすべての関数__repr__()、オブジェクトのを。

4)__str__()コンテナの場合、呼び出されると__repr__()、含まれている要素のメソッドを実行します。

5)str()内で呼び出されると__str__()、基本ケースなしで再帰する可能性があり、最大再帰深度でエラーが発生します。

6)__repr__()repr()、無限の再帰を自動的に回避しようとする呼び出しを行うことができ、すでに表されているオブジェクトをで置き換えます...


14

簡単に言えば:

__str__簡単に読み取られるオブジェクトの文字列表現を表示するために使用されます、他。

__repr__文字列表現を示すために使用されているオブジェクトを。

Fraction分数の文字列表現が '(1/2)'であり、オブジェクト(Fractionクラス)が 'Fraction(1,2)'として表されるクラスを作成するとします。

したがって、単純なFractionクラスを作成できます。

class Fraction:
    def __init__(self, num, den):
        self.__num = num
        self.__den = den

    def __str__(self):
        return '(' + str(self.__num) + '/' + str(self.__den) + ')'

    def __repr__(self):
        return 'Fraction (' + str(self.__num) + ',' + str(self.__den) + ')'



f = Fraction(1,2)
print('I want to represent the Fraction STRING as ' + str(f)) # (1/2)
print('I want to represent the Fraction OBJECT as ', repr(f)) # Fraction (1,2)

13

すべての正直でeval(repr(obj))は、決して使用されません。それを使用していることに気づいた場合は、停止する必要evalがあります。危険であり、文字列はオブジェクトをシリアル化するための非常に非効率的な方法です(使用pickle代わりに)。

したがって、を設定することをお勧めします__repr__ = __str__。その理由は、要素のstr(list)呼び出しreprです(これは、Python 3で対処されなかったPythonの最大の設計上の欠陥の1つであると私は考えています)。実際reprの出力は、の出力としてはあまり役に立ちませんprint [your, objects]

これを修飾するために、私の経験では、このrepr関数の最も有用な使用例は、(文字列フォーマットを使用して)別の文字列の中に文字列を置くことです。このようにして、引用符やその他のエスケープについて心配する必要はありません。ただし、evalここでは何も起こりません。


19
これは要点を逃していると思います。の使用eval(repr(obj))は健全性テストであり、経験則です。これにより元のオブジェクトが正しく再作成された場合、適切な__repr__実装になります。この方法でオブジェクトを実際にシリアル化することは意図されていません。
jwg 14

7
eval本質的に危険ではありません。よりも危険ではありませんunlinkopenまたはファイルへの書き込み。おそらく悪意のある攻撃が任意のファイルパスを使用してコンテンツを内部に配置できるため、ファイルへの書き込みを停止する必要がありますか?ばかばかしい人にばかばかしく使われると、すべてが危険です。愚かなことは危険です。督促クルーガー効果は危険です。eval単なる関数です。
Luis Masuelli、2016年

12

(アン非公式)PythonリファレンスのWiki(アーカイブ・コピー) effbotによって:

__str__" は、オブジェクトの「非公式」の文字列表現を計算します。これは__repr__、有効なPython式である必要がないという点で異なります。代わりに、より便利で簡潔な表現を使用できます。 "


3
__repr__有効なPython式を返すために必要なことではありません。
マッド

10

str -指定されたオブジェクトから新しい文字列オブジェクトを作成します。

repr -オブジェクトの正規の文字列表現を返します。

違い:

str():

  • オブジェクトを読み取り可能にします
  • エンドユーザー向けの出力を生成します

repr():

  • オブジェクトを再現するコードが必要
  • 開発者向けの出力を生成します

8

他の回答にはない1つの側面。一般に、パターンは次のとおりです。

  • の目標 __str__:人間が読める
  • 目標__repr__:明確で、おそらく機械可読なeval

残念ながら、この違いには欠陥があります。PythonREPLおよびIPython __repr__がREPLコンソールでオブジェクトを印刷するために使用するためです(PythonおよびIPythonの関連する質問を参照してください)。したがって、インタラクティブなコンソール作業を対象とするプロジェクト(NumpyやPandasなど)は、上記のルールを無視し、人間が読める形式の__repr__実装を提供するようになりました。


7

Fluent Pythonの本から:

Pythonオブジェクトの基本的な要件は、それ自体の使用可能な文字列表現を提供することです。1つはデバッグとロギングに使用され、もう1つはエンドユーザーへの表示に使用されます。これが、
特別なメソッドで__repr__あり__str__、データモデルに存在する理由です。


5

優秀な答えはすでに違い網羅__str__し、__repr__開発者にできるだけとして有用な、私にとって読みやすいでも、エンドユーザーによって前者はつまるところ、そして後者を。ことを考えると、私はデフォルトの実装がわかり__repr__、多くの場合は、この目標を達成するために失敗したので、それを省い、開発者に役立つ情報が。

このため、十分__str__に単純な場合は、通常、次のようなものを使用して両方の世界の最高のものを取得しようとします。

def __repr__(self):
    return '{0} ({1})'.format(object.__repr__(self), str(self))

4

心に留めておくべき重要なことの1つは、コンテナの__str__使用に含まれるオブジェクトの使用です__repr__

>>> from datetime import datetime
>>> from decimal import Decimal
>>> print (Decimal('52'), datetime.now())
(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 51, 26, 185000))
>>> str((Decimal('52'), datetime.now()))
"(Decimal('52'), datetime.datetime(2015, 11, 16, 10, 52, 22, 176000))"

Pythonは読みやすさを超える曖昧を好む__str__の呼び出しがtuple含まれているオブジェクトを呼び出して__repr__『正式な』オブジェクトの表現。形式的な表現は、非形式的な表現よりも読みにくいですが、明確であり、バグに対してより堅牢です。


__repr____str__)が定義されていないときに使用します!だから、あなたは間違っています。
jiten 2018

4

手短に:

class Demo:
  def __repr__(self):
    return 'repr'
  def __str__(self):
    return 'str'

demo = Demo()
print(demo) # use __str__, output 'str' to stdout

s = str(demo) # __str__ is used, return 'str'
r = repr(demo) # __repr__ is used, return 'repr'

import logging
logger = logging.getLogger(logging.INFO)
logger.info(demo) # use __str__, output 'str' to stdout

from pprint import pprint, pformat
pprint(demo) # use __repr__, output 'repr' to stdout
result = pformat(demo) # use __repr__, result is string which value is 'str'

4
>>> print(decimal.Decimal(23) / decimal.Decimal("1.05"))
21.90476190476190476190476190
>>> decimal.Decimal(23) / decimal.Decimal("1.05")
Decimal('21.90476190476190476190476190')

場合print()の結果で呼び出されたdecimal.Decimal(23) / decimal.Decimal("1.05")生番号印刷されます。この出力は、で実現できる文字列形式__str__()です。式を入力するだけでdecimal.Decimal出力が得られます。この出力は、で実現できる表現形式__repr__()です。すべてのPythonオブジェクトには2つの出力形式があります。文字列形式は人間が読めるように設計されています。表現形式は、Pythonインタープリターに渡された場合に(可能な場合)表現されたオブジェクトを再現する出力を生成するように設計されています。


4

__str__を呼び出すことでオブジェクトに対して呼び出すことができstr(obj)、人間が読める文字列を返す必要があります。

__repr__を呼び出すことによってオブジェクトで呼び出すことができ、repr(obj)内部オブジェクト(オブジェクトフィールド/属性)を返す必要があります

この例は役立つかもしれません:

class C1:pass

class C2:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")

class C3:        
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")

class C4:        
    def __str__(self):
        return str(f"{self.__class__.__name__} class str ")
    def __repr__(self):        
         return str(f"{self.__class__.__name__} class repr")


ci1 = C1()    
ci2 = C2()  
ci3 = C3()  
ci4 = C4()

print(ci1)       #<__main__.C1 object at 0x0000024C44A80C18>
print(str(ci1))  #<__main__.C1 object at 0x0000024C44A80C18>
print(repr(ci1)) #<__main__.C1 object at 0x0000024C44A80C18>
print(ci2)       #C2 class str
print(str(ci2))  #C2 class str
print(repr(ci2)) #<__main__.C2 object at 0x0000024C44AE12E8>
print(ci3)       #C3 class repr
print(str(ci3))  #C3 class repr
print(repr(ci3)) #C3 class repr
print(ci4)       #C4 class str 
print(str(ci4))  #C4 class str 
print(repr(ci4)) #C4 class repr

3

理解__str__して__repr__それらを直感的かつ永続的に区別します。

__str__ 目が読めるように、指定されたオブジェクトの文字列を偽装したボディを返します
__repr__ように返す明確にするために、特定のオブジェクトの実際の肉体を返す(それ自体を返す)。

例で見る

In [30]: str(datetime.datetime.now())
Out[30]: '2017-12-07 15:41:14.002752'
Disguised in string form

に関して __repr__

In [32]: datetime.datetime.now()
Out[32]: datetime.datetime(2017, 12, 7, 15, 43, 27, 297769)
Presence in real body which allows to be manipulated directly.

__repr__結果の算術演算を手軽に行うことができます。

In [33]: datetime.datetime.now()
Out[33]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521)
In [34]: datetime.datetime(2017, 12, 7, 15, 47, 9, 741521) - datetime.datetime(2
    ...: 017, 12, 7, 15, 43, 27, 297769)
Out[34]: datetime.timedelta(0, 222, 443752)

操作を適用する場合 __str__

In [35]: '2017-12-07 15:43:14.002752' - '2017-12-07 15:41:14.002752'
TypeError: unsupported operand type(s) for -: 'str' and 'str'

エラーのみを返します。

もう一つの例。

In [36]: str('string_body')
Out[36]: 'string_body' # in string form

In [37]: repr('real_body')
Out[37]: "'real_body'" #its real body hide inside

これが具体的な根拠を築き、より多くの答えを探すのに役立つことを願っています。


3
  1. __str__文字列オブジェクトを返す必要がありますが、__repr__任意のPython式を返すことができます。
  2. __str__実装が欠落している場合、__repr__関数はフォールバックとして使用されます。__repr__関数の実装が欠落している場合、フォールバックはありません。
  3. __repr__関数がオブジェクトの文字列表現を返す場合、関数の実装をスキップでき__str__ます。

ソース:https : //www.journaldev.com/22460/python-str-repr-functions


2

__repr__printstrメソッドを除いて、どこでも使用されます(a __str__が定義されている場合!)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.