日付を持たない時刻を扱う時計を実装しましょう。
その時計では、分を足したり引いたりできるようにします。
同じ時刻を表す2つの時計は、互いに等しくなければなりません。
この演習のテストでは、時計がClockというclassとして実装されることを想定しています。
Pythonのクラスに馴染みがない場合は、classes と classes(Pythonのドキュメントより)が良い出発点になります。
オブジェクトを扱ったりデバッグしたりするときは、そのオブジェクトをうまく表現できることが重要です。
たとえば、PythonのREPL環境で新しいdatetime.datetimeオブジェクトを作成すると、その文字列表現を確認できます。
>>> from datetime import datetime
>>> new_date = datetime(2022, 5, 4)
>>> new_date
datetime.datetime(2022, 5, 4, 0, 0)
Clockclassは、日付_なし_で時刻を扱う独自のobjectを作成する必要があります。
このclassの重要な側面の1つは、どのように_文字列_として表現されるかです。
Clockclassから作られたClockobjectsを使ったり呼び出したりする他のプログラマーは、デバッグやその他の作業のためにこの文字列表現を参照します。
ただし、独自のclassにおけるデフォルトの表現は、あまり役に立ちません。
>>> Clock(12, 34)
<Clock object st 0x102807b20 >
より役に立つ表現を作るには、classに__repr__という特殊メソッドを定義します。
理想的には、その__repr__メソッドは、eval()に渡すとオブジェクトを再作成できる有効なPythonコードを返します。これは__repr__メソッドの仕様に示されているとおりです。
有効なPythonコードを返すようにすると、他のエンジニアがstrをそのままコードやREPLにコピー&ペーストできるようになります。
午前11時30分を表すClockは、次のようになります。
`Clock(11, 30)`
__repr__メソッドを定義するのは、すべての独自クラスにとって良い習慣です。
さらに、次の点も考慮するとよいでしょう。
<>)の間に説明を書いて返すのが慣習です: < ...a practical description... >
__repr__メソッドに加えて、classを「人間が読める」形で表す、別の文字列表現が必要になることもあります。
これは、プログラムの出力やドキュメントのためにオブジェクトを整形するのに使われることがあります。
これは、__str__という特殊メソッドを書くことで行います。
もう一度datetime.datetimeを見てみましょう。
>>> str(datetime.datetime(2022, 5, 4))
'2022-05-04 00:00:00'
datetimeオブジェクトに文字列表現への変換を求めると、ISO 8601標準に従って整形されたstrを返します。これはほとんどのdatetimeライブラリで、人間が読める日付と時刻に解析できます。
この演習では、Clockのための__str__メソッドと、__repr__メソッドを書く機会があります。
>>> str(Clock(11, 30))
'11:30'
この文字列変換に対応するには、classに__str__特殊メソッドを作成し、Clockの時刻を示すより「人間が読める」文字列を返す必要があります。
__str__メソッドを作成せずにクラスに対してstr()を呼び出すと、Pythonはフォールバックとしてそのクラスの__repr__を呼び出そうとします。
ですから、この2つの特殊メソッドのうち片方だけを実装するなら、__str__だけを作るよりも__repr__を作るほうがよいでしょう。