__str__と__repr__の目的は何ですか?[複製]


83

Pythonのどこにあり__str____repr__使用されているのか本当にわかりません。つまり__str__、オブジェクトの文字列表現を返すことがわかります。しかし、なぜ私はそれが必要なのでしょうか?どのようなユースケースシナリオで?また、私はの使用法について読みました__repr__

しかし、私が理解していないのは、どこでそれらを使用するのかということです。



4
Rubyから来た人にとって、tl; drは__str__=to_s__repr__=inspectです。
ajedi32 2015年

3
これはあなたの質問に答えますか?__str__と__repr__の違いは?
xiaoouwang20年

回答:


86

__repr__

repr()オブジェクトの「公式」文字列表現を計算するために、組み込み関数および文字列変換(逆引用符)によって呼び出されます。可能であれば、これは、同じ値でオブジェクトを再作成するために使用できる有効なPython式のように見えるはずです(適切な環境が与えられた場合)。

__str__

str()組み込み関数とprintステートメントによって呼び出され、オブジェクトの「非公式」文字列表現を計算します。

使用__str__あなたは、クラスを持っている、とあなたは文字列の一部としてこのオブジェクトを使用するたびに、有益/非公式の出力をお勧めします場合。たとえば__str__、Djangoモデルのメソッドを定義して、Django管理インターフェースでレンダリングすることができます。<Model object>あなたのようなものの代わりに、人の姓名、イベントの名前と日付などが表示されます。


__repr____str__は似ていますが、実際には等しい場合があります(標準ライブラリのBaseSetクラスの例sets.py):

def __repr__(self):
    """Return string representation of a set.

    This looks like 'Set([<list of elements>])'.
    """
    return self._repr()

# __str__ is the same as __repr__
__str__ = __repr__

1
ありがとう!これはまさに私が探していたものです!
ダニエル

`return self._repr()`が何をするか、コードを実行してそれを理解しようとすると、__ repr __()はちょうど1つの引数を取ると言います。
2015

では、djangoの__repr__代わりに使用でき__str__ますか?
Amit Tripathi 2015年

61

両方を頻繁に使用する1つの場所は、インタラクティブセッションです。オブジェクトを印刷すると、その__str__メソッドが呼び出されますが、オブジェクトを単独で使用する場合__repr__は、次のように表示されます。

>>> from decimal import Decimal
>>> a = Decimal(1.25)
>>> print(a)
1.25                  <---- this is from __str__
>>> a
Decimal('1.25')       <---- this is from __repr__

__str__一方、人間が読める可能な限りであることを意図している__repr__ことが多いことが、この場合のように、作成された正確にどのようにされませんが、オブジェクトを再作成するために使用できるものにすることを目指すべきです。

これは、両方のためにも珍しいことではありません__str__し、__repr__(確かにビルトインタイプ用)と同じ値を返します。


例をありがとう、これがデフォルトで使用される場所のより良い理解を私に与えました
JayRizzo 2018

17

バッタ、疑わしいときは山に行って古代のテキスト読んでください。それらの中には、__ repr __()が次のようになっていることがわかります。

可能であれば、これは同じ値でオブジェクトを再作成するために使用できる有効なPython式のように見えるはずです。


6
-1は、実際の質問に答えようとさえしないためです。これがユースケースです。
スコットグリフィス

4
@スコット:その通りです。しかし、実際の質問では、そもそもプライマリドキュメントに移動する試みはまったくありませんでした。自分で答えようとしたが、それでも少し混乱していることを示す質問をすることと、このような質問を投稿することは別のことです。新しい質問として件名を入力するだけで、上位6つの提案されたSOスレッドのうち5つが彼の質問に答えたはずですが、彼は気にすることができませんでした。私は彼にlmgtfyの答えを完全には与えませんでしたが、私はひどく誘惑されました。
Peter Rowell 2010

1
実際、彼は読んだと言っていましたが__repr__、公式ドキュメントでは、なぜそれを使用するのかについての質問には実際には答えていません。また、質問が他の場所で答えられたからといって、そうでない理由にはなりません。 SOで回答しました(グーグルではない場合が多いので、ここに戻ってきます!)質問に回答する価値がないと思われる場合は、回答できませんでしたが、この場合は、すでに十分にカバーされていることに同意しますSOなど、重複へのリンクは適切な対応です。
スコットグリフィス

実際、あなたは間違っています。ドキュメントには、なぜそれを使用するのかが明確に示されています。「これは通常、デバッグに使用されるため、情報が豊富で明確であることが重要です。」Help Vampiresの重みで沈むフォーラム(フォーラム?)が多すぎるのを見てきましたが、SOに移行し始めているのを見るのは辛いです。他の明白なSO回答へのリンクに関しては、それが件名を入力するときに開始される提案メカニズムの全体的な目的ですが、彼はすべての提案を無視することを選択しました。QED&PDQも。
Peter Rowell 2010

5
まあ、ドキュメントはまだデバッグのためにそれを使用する方法を述べていませんが、私は本当にこれについて議論するつもりはありませんでした。私たちは少なくともあなたの答えが質問に対処しなかったことに同意します、それで私の-1はまだ私に正当化されていると感じます。質問の記述が不十分/重複/些細な場合は、質問を改善したり、重複にリンクしたり、単に質問に反対票を投じたりすることができます。ここでの私の主な異議は、答えは質問に答えようとするべきだということだと思います-質問を批判するための他のメカニズムがあります。私たち二人ともここでもっと良いことがあると思うので、今は黙ります。
スコットグリフィス

14

以前の回答に基づいて、さらにいくつかの例を示します。適切に使用された場合は、違いstrとはrepr明らかです。要するにrepr一方、コピー貼り付けたオブジェクトの正確な状態を再構築することができる文字列を返すべきであるstrのに有用であるloggingobservingデバッグ結果。いくつかの既知のライブラリのさまざまな出力を確認するためのいくつかの例を次に示します。

日付時刻

print repr(datetime.now())    #datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)
print str(datetime.now())     #2017-12-12 18:49:27.134452

strログファイル、に印刷するための良いですがrepr、あなたがそれを直接実行したり、ファイルにコマンドとしてそれをダンプしたい場合は、再目的とすることができます。

x = datetime.datetime(2017, 12, 12, 18, 49, 27, 134411)

ナンピー

print repr(np.array([1,2,3,4,5])) #array([1, 2, 3, 4, 5])
print str(np.array([1,2,3,4,5]))  #[1 2 3 4 5]

Numpyでは、これreprも直接消耗品です。

カスタムVector3の例

class Vector3(object):
    def __init__(self, args):
        self.x = args[0]
        self.y = args[1]
        self.z = args[2]

    def __str__(self):
        return "x: {0}, y: {1}, z: {2}".format(self.x, self.y, self.z)

    def __repr__(self):
        return "Vector3([{0},{1},{2}])".format(self.x, self.y, self.z)

この例でreprは、直接消費/実行できる文字列を再び返しますがstr、デバッグ出力としてはより便利です。

v = Vector3([1,2,3])
print str(v)     #x: 1, y: 2, z: 3
print repr(v)    #Vector3([1,2,3])

str定義されていないがreprstrが自動的にを呼び出すことを覚えておいてreprください。したがって、少なくとも定義することは常に良いことですrepr


5

__str__関数のないクラスを作成しましょう。

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

emp1 = Employee('Ivan', 'Smith', 90000)

print(emp1)

クラスのこのインスタンスを出力するとemp1、次のようになります。

<__main__.Employee object at 0x7ff6fc0a0e48>

これはあまり役に立ちません。確かに、これを使用して表示する場合(htmlのように)、これは印刷したいものではありません。

だから今、同じクラスですが、__str__関数があります:

class Employee:

    def __init__(self, first, last, pay):
        self.first = first 
        self.last = last
        self.pay = pay

    def __str__(self):
        return(f"The employee {self.first} {self.last} earns {self.pay}.")
        # you can edit this and use any attributes of the class

emp2 = Employee('John', 'Williams', 90000)

print(emp2)

これで、オブジェクトがあることを出力する代わりに、__str__関数の戻りで指定したものを取得します。

The employee John Williams earns 90000


3

str非公式で読みやすい形式になりますreprが、公式のオブジェクト表現を提供します。

class Complex:
    # Constructor
    def __init__(self, real, imag):
        self.real = real
        self.imag = imag

    # "official" string representation of an object
    def __repr__(self):
        return 'Rational(%s, %s)' % (self.real, self.imag)

    # "informal" string representation of an object (readable)
    def __str__(self):
        return '%s + i%s' % (self.real, self.imag)

    t = Complex(10, 20)

    print (t)     # this is usual way we print the object
    print (str(t))  # this is str representation of object 
    print (repr(t))  # this is repr representation of object   

Answers : 

Rational(10, 20) # usual representation
10 + i20      # str representation
Rational(10, 20)  # repr representation

1

strreprはどちらも表現する方法です。クラスを書いているときにそれらを使用することができます。

class Fraction:
def __init__(self, n, d):
    self.n = n
    self.d = d
def __repr__(self):
    return "{}/{}".format(self.n, self.d)

たとえば、そのインスタンスを印刷すると、物が返されます。

print(Fraction(1, 2))

結果は

1/2

一方

class Fraction:
def __init__(self, n, d):
    self.n = n
    self.d = d
def __str__(self):
    return "{}/{}".format(self.n, self.d)
print(Fraction(1, 2))

また、結果として

1/2

しかし、両方を書くと、Pythonはどちらを使用しますか?

class Fraction:
def __init__(self, n, d):
    self.n = n
    self.d = d
def __str__(self):
    return "str"
def __repr__(self):
    return "repr"

print(Fraction(None, None))

これにより、

str

したがって、Pythonは、両方が記述されている場合、実際にはreprメソッドではなくstrメソッドを使用します


0

クラスがあり、インスタンスを検査したい場合、印刷物はあまり有用な情報を提供していないことがわかります

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age


p1 = Person("John", 36)
print(p1)  # <__main__.Animal object at 0x7f9060250410>

ここで、strを含むクラスを参照してください。インスタンス情報が表示され、reprを使用すると、印刷する必要もありません。いいじゃない?

class Animal:
    def __init__(self, color, age, breed):
        self.color = color
        self.age = age
        self.breed = breed

    def __str__(self):
        return f"{self.color} {self.breed} of age {self.age}"

    def __repr__(self):
        return f"repr : {self.color} {self.breed} of age {self.age}"


a1 = Animal("Red", 36, "Dog")
a1  # repr : Red Dog of age 36
print(a1)  # Red Dog of age 36
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.