Pythonのどこにあり__str__、__repr__使用されているのか本当にわかりません。つまり__str__、オブジェクトの文字列表現を返すことがわかります。しかし、なぜ私はそれが必要なのでしょうか?どのようなユースケースシナリオで?また、私はの使用法について読みました__repr__
しかし、私が理解していないのは、どこでそれらを使用するのかということです。
Pythonのどこにあり__str__、__repr__使用されているのか本当にわかりません。つまり__str__、オブジェクトの文字列表現を返すことがわかります。しかし、なぜ私はそれが必要なのでしょうか?どのようなユースケースシナリオで?また、私はの使用法について読みました__repr__
しかし、私が理解していないのは、どこでそれらを使用するのかということです。
__str__=to_sと__repr__=inspectです。
回答:
repr()オブジェクトの「公式」文字列表現を計算するために、組み込み関数および文字列変換(逆引用符)によって呼び出されます。可能であれば、これは、同じ値でオブジェクトを再作成するために使用できる有効なPython式のように見えるはずです(適切な環境が与えられた場合)。
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__
__repr__代わりに使用でき__str__ますか?
両方を頻繁に使用する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__(確かにビルトインタイプ用)と同じ値を返します。
__repr__、公式ドキュメントでは、なぜそれを使用するのかについての質問には実際には答えていません。また、質問が他の場所で答えられたからといって、そうでない理由にはなりません。 SOで回答しました(グーグルではない場合が多いので、ここに戻ってきます!)質問に回答する価値がないと思われる場合は、回答できませんでしたが、この場合は、すでに十分にカバーされていることに同意しますSOなど、重複へのリンクは適切な対応です。
以前の回答に基づいて、さらにいくつかの例を示します。適切に使用された場合は、違いstrとはrepr明らかです。要するにrepr一方、コピー貼り付けたオブジェクトの正確な状態を再構築することができる文字列を返すべきであるstrのに有用であるloggingとobservingデバッグ結果。いくつかの既知のライブラリのさまざまな出力を確認するためのいくつかの例を次に示します。
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も直接消耗品です。
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定義されていないがrepr、strが自動的にを呼び出すことを覚えておいてreprください。したがって、少なくとも定義することは常に良いことですrepr
__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
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
strとreprはどちらも表現する方法です。クラスを書いているときにそれらを使用することができます。
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メソッドを使用します。
クラスがあり、インスタンスを検査したい場合、印刷物はあまり有用な情報を提供していないことがわかります
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