Python repr()の動作をクラスとformat()で確認

Python学習【365日チャレンジ!】294日目のマスターU(@Udemy11)です。

今日から師走ですね。

師匠も走るくらい忙しいってことで師走らしいのですが、普段の師匠は走らなかったんでしょうね。

朝晩の寒さも本格化してきて、朝起きるのがつらくなってくると布団から出たくなくなりますよね。

かといって1日中寝ているわけにもいきませんし、何といってもトイレにいかないと行けません。

布団から出るのが嫌なので、冬は紙おむつをはいて寝てるなんて人がいるとかいないとか。。。

それでは今日も、Python学習を始めましょう。

昨日の復習

昨日は、Pythonオブジェクトのデータを取得するrepr()を学習しました。

値をprint出力するときは、Pythonが文字列と認識するための'は出力されませんが、repr()を使って値をprint出力すれば、'で挟まれたPythonオブジェクトとして値が出力されます。

対話型シェルを使って変数を出力するときは、デフォルトでPythonオブジェクトとして出力されるので、'で挟まれた値が出力されますが、print出力にすると、'が外されて出力されました。

詳しくは昨日の記事をごらんください。

今日は、formatとクラスオブジェクトを使ってreprの動作をチェックしてみます。

format

formatを使ってrepr()を表示するには、!rを使います。

print('{!r} {} {!s}'.format('test1', 'test2', 'test3'))

出力結果

'test1' test2 test3

!rrepr()を出力して、!sstr()を出力しています。

class

次に、何もしないクラスを使って3種類の出力をしてみます。

class RepTest(object):
    pass

r = RepTest()
print('{0!r}'.format(r))
print('{0}'.format(r))
print('{0!s}'.format(r))

何もしないクラスRepTestを作成して、クラスオブジェクトを生成したあと、クラスオブジェクトをrepr、そのまま代入、strの順にformatで出力しています。

出力結果

<__main__.RepTest object at 0x7ff24549ffd0>
<__main__.RepTest object at 0x7ff24549ffd0>
<__main__.RepTest object at 0x7ff24549ffd0>

クラスオブジェクトからは何も返されていないので、3つともPythonオブジェクトが返されています。

__str__

次は、クラスで__str__をオーバーライドして出力してみます。

class RepTest(object):
    def __str__(self)
        return 'string'

r = RepTest()
print('{0!r}'.format(r))
print('{0}'.format(r))
print('{0!s}'.format(r))

クラスの__str__を文字列のstringを返すようにオーバーライドしました。

出力結果

<__main__.RepTest object at 0x7f9ac08a7110>
string
string

reprの出力は先程と変わらずPythonオブジェクトですが、7行目、8行目の出力は、stringに変わりました。

__str__

次は、さらにクラスで__repr__をオーバーライドして出力してみます。

class RepTest(object):
    def __repr__(self):
        return 'ReprObject'
    def __str__(self)
        return 'string'

r = RepTest()
print('{0!r}'.format(r))
print('{0}'.format(r))
print('{0!s}'.format(r))

通常は__repr__をオーバーライドすることはありませんが、文字列のReprObjectを返すようにオーバーライドしています。

出力結果

ReprObject
string
string

reprの出力も文字列ReprObjectに置き換わりました。

__init__

最後に__init__で引数を定義して、__str__()formatを使って引数を活用してみます。

class ReprTest(object):
    def  __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'repr objectd'

    def __str__(self):
        return 'num ({}, {})'.format(self.x, self.y)


p = ReprTest(10, 20)
print('{0!r}'.format(p))
print('{0}'.format(p))
print('{0!s}'.format(p))

__init__で引数xyを定義して、__str__formatを使ってnum (x, y)を返すように定義しています

出力結果

repr objectd
num (10, 20)
num (10, 20)

reprの出力は先程と同じReprObjectですが、15行目、16行目の出力が、10行目で定義したnum(10, 20)に変わっています。

まとめ

クラスにはデフォルトで__str____repr__が定義されているので、オーバーライドして書き換えることができますが、用途を理解してオーバーライドする必要があります。

__repr__を書き換えることはないと書きましたが、今回オーバーライドしたことで、本来Pythonオブジェクトが返されるところに、文字列が返されてしまいました。

酒井さんの講座を受講していていつも思うのですが、やはり、講座を受講するだけでは理解できていないこともいろいろ試しながらコードを書いていればなんとなくの使い方がわかってきます。

Udemyのサイバーウィークセールを実施しているこの機会にぜひ、酒井さんの講座を受講してみてはどうでしょうか?

Udemy講師 酒井さん プログラミング Python

ということで、明日もGood Python!