回答:
アレックスはうまくまとめましたが、驚いたことに、簡潔すぎました。
まず、アレックスの投稿の要点を繰り返します。
__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__
読みやすさの面でエラーのある文字列バージョンがあると便利な場合に実装します。
__repr__
、デバッグに必要なことがわかりました。ご協力ありがとうございました。
私の経験則: __repr__
開発者__str__
向け、顧客向けです。
__str__
、通常の開発者が読み取り可能なオブジェクトを使用するようにします。一方、__repr__
SDK開発者自身のためです。
特にそうでないことを確認するために特別に行動しない限り、ほとんどのクラスには、次のいずれについても役立つ結果がありません。
>>> 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__
eval(repr(foo))
、がと等しいオブジェクトに評価されることを常に確認しますfoo
。モジュールのインポート方法がわからないので、テストケース以外では機能しませんが、これにより、少なくとも一部の予測可能なコンテキストで機能することが保証されます。これは、結果が__repr__
十分に明確かどうかを評価する良い方法だと思います。単体テストでこれを行う__repr__
と、クラスの変更を確実に追跡できます。
eval(repr(spam)) == spam
(少なくとも正しいコンテキストでは)またはeval(repr(spam))
を発生させることを常に確認しようとしSyntaxError
ます。そうすれば混乱を避けることができます。(そして、それはだ、ほとんど組み込みコマンドのために真とSTDLIBのほとんどを除いて、例えば、再帰的なリスト、a=[]; a.append(a); print(eval(repr(a)))
あなたが与える[[Ellipses]]
...)もちろん私は実際にすることをしない使用 eval(repr(spam))
ユニットテストでの健全性チェックなどを除き、...しかし、私は、時にはコピー&ペーストインタラクティブセッションに。repr(spam)
__str__
ではなく、各要素に使用しないのはなぜ __repr__
ですか?__str__
私はオブジェクトにリーダブルを実装し、それがリストの一部である場合、__repr__
代わりに醜いものを見るので、私には明白に間違っているようです。
eval(repr(x))
組み込み型でも失敗するという事実に関連する厄介なバグに遭遇しただけで、class A(str, Enum): X = 'x'
SyntaxErrorが発生しeval(repr(A.X))
ます。悲しいですが、理解できます。ところで、eval(str(A.X))
実際には機能しますが、もちろんclass A
範囲内にある場合に限られます。したがって、おそらくあまり役に立ちません。
str
は要素を使用します。repr
[1, 2, 3]
["1", "2, 3"]
__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
要するに、の目標
__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()
です。その目的は、印刷可能な文字列を返すことです。引数を指定しない場合、空の文字列を返します''
。
違いは何である
__str__
と__repr__
Pythonでは?
__str__
(「dunder(double-underscore)string」と読みます)そして __repr__
として読み取られます(「dunder-repper」(「表現」のために読み取られます))は、どちらもオブジェクトの状態に基づいて文字列を返す特別なメソッドです。
__repr__
__str__
がない場合のバックアップ動作を提供します。
したがって、最初に、__repr__
たとえば、使用するeval
か、Pythonシェルで文字ごとに入力することによって、返される文字列から同等のオブジェクトをインスタンス化できるようにするを記述します。
後でいつでも、__str__
それが必要だと思われるときに、ユーザーが読み取れるインスタンスの文字列表現を記述できます。
__str__
あなたは、オブジェクトを印刷、またはにそれを渡した場合format
、str.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__
でしょうか?
ハンス・ペッター・ラングタンゲンの著書「計算科学のためのPythonスクリプト」の358ページには、
__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'
repr
再生と呼ぶのは誤解を招くようなものです。それを代表するものと考えるのが良いでしょう。
与えられたすべての回答とは別に、いくつかのポイントを追加したいと思います:-
1)__repr__()
インタラクティブなPythonコンソールでオブジェクトの名前を入力してEnterキーを押すと呼び出されます。
2)__str__()
printステートメントでオブジェクトを使用すると呼び出されます。
3)__str__
不足している場合は、印刷とstr()
呼び出しを使用するすべての関数__repr__()
、オブジェクトのを。
4)__str__()
コンテナの場合、呼び出されると__repr__()
、含まれている要素のメソッドを実行します。
5)str()
内で呼び出されると__str__()
、基本ケースなしで再帰する可能性があり、最大再帰深度でエラーが発生します。
6)__repr__()
はrepr()
、無限の再帰を自動的に回避しようとする呼び出しを行うことができ、すでに表されているオブジェクトをで置き換えます...
。
簡単に言えば:
__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)
すべての正直でeval(repr(obj))
は、決して使用されません。それを使用していることに気づいた場合は、停止する必要eval
があります。危険であり、文字列はオブジェクトをシリアル化するための非常に非効率的な方法です(使用pickle
代わりに)。
したがって、を設定することをお勧めします__repr__ = __str__
。その理由は、要素のstr(list)
呼び出しrepr
です(これは、Python 3で対処されなかったPythonの最大の設計上の欠陥の1つであると私は考えています)。実際repr
の出力は、の出力としてはあまり役に立ちませんprint [your, objects]
。
これを修飾するために、私の経験では、このrepr
関数の最も有用な使用例は、(文字列フォーマットを使用して)別の文字列の中に文字列を置くことです。このようにして、引用符やその他のエスケープについて心配する必要はありません。ただし、eval
ここでは何も起こりません。
eval(repr(obj))
は健全性テストであり、経験則です。これにより元のオブジェクトが正しく再作成された場合、適切な__repr__
実装になります。この方法でオブジェクトを実際にシリアル化することは意図されていません。
eval
本質的に危険ではありません。よりも危険ではありませんunlink
、open
またはファイルへの書き込み。おそらく悪意のある攻撃が任意のファイルパスを使用してコンテンツを内部に配置できるため、ファイルへの書き込みを停止する必要がありますか?ばかばかしい人にばかばかしく使われると、すべてが危険です。愚かなことは危険です。督促クルーガー効果は危険です。eval
単なる関数です。
(アン非公式)PythonリファレンスのWiki(アーカイブ・コピー) effbotによって:
__str__
" は、オブジェクトの「非公式」の文字列表現を計算します。これは__repr__
、有効なPython式である必要がないという点で異なります。代わりに、より便利で簡潔な表現を使用できます。 "
__repr__
有効なPython式を返すために必要なことではありません。
Fluent Pythonの本から:
Pythonオブジェクトの基本的な要件は、それ自体の使用可能な文字列表現を提供することです。1つはデバッグとロギングに使用され、もう1つはエンドユーザーへの表示に使用されます。これが、
特別なメソッドで__repr__
あり__str__
、データモデルに存在する理由です。
優秀な答えはすでに違い網羅__str__
し、__repr__
開発者にできるだけとして有用な、私にとって読みやすいでも、エンドユーザーによって前者はつまるところ、そして後者を。ことを考えると、私はデフォルトの実装がわかり__repr__
、多くの場合は、この目標を達成するために失敗したので、それを省い、開発者に役立つ情報が。
このため、十分__str__
に単純な場合は、通常、次のようなものを使用して両方の世界の最高のものを取得しようとします。
def __repr__(self):
return '{0} ({1})'.format(object.__repr__(self), str(self))
心に留めておくべき重要なことの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__
)が定義されていないときに使用します!だから、あなたは間違っています。
手短に:
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'
>>> 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インタープリターに渡された場合に(可能な場合)表現されたオブジェクトを再現する出力を生成するように設計されています。
__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
理解__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
これが具体的な根拠を築き、より多くの答えを探すのに役立つことを願っています。
__str__
文字列オブジェクトを返す必要がありますが、__repr__
任意のPython式を返すことができます。__str__
実装が欠落している場合、__repr__
関数はフォールバックとして使用されます。__repr__
関数の実装が欠落している場合、フォールバックはありません。__repr__
関数がオブジェクトの文字列表現を返す場合、関数の実装をスキップでき__str__
ます。ソース:https : //www.journaldev.com/22460/python-str-repr-functions