▶ クラスの基本から確認するには以下の記事を参考にしてください。
はじめに
今回はここまで学んできたことを使ってクラスを作成してみましょう。クラスの作り方、インスタンス変数・クラス変数、インスタンスメソッド・スタティックメソッドの知識を使ったクラスを作ってみましょう。今回はどうぶつえんに来園するどうぶつたちの来園回数や何名できたかなどがわかる「来園管理」の仕組みを作ってみることにしましょう。
クラスを作る
はじめにやりたいことを書きだしてみましょう。
変数とメソッドを考える
書き出したものはまだ抽象的ですね。これを具体化していきましょう。まずは「変数」と「メソッド」にわけてそれぞれ、変数は「インスタンス変数」とするのがよいか、「クラス変数」とするのが良いか、メソッドは「インスタンスメソッド」とするのがよいか、「スタティックメソッド」とするのがよいかを考えてみましょう。
※「クラスメソッド」はまだ扱っていないので、まずは上記のように考えてみましょう。
まずどうぶつえんに来園するどうぶつたちは、来園するどうぶつごとにインスタンスを作ることにしましょう。「会員番号」「名前」「年齢」はインスタンス変数とするのがよさそうですね。
「会員番号」についてはインスタンス変数ですが、クラス変数numberも定義して、インスタンスが生成するたびに(初期化メソッドが呼ばれるたびに)カウントアップするようにして、インスタンス生成時にそのクラス変数を初期値としてセットするようにしましょう。
「来園回数」はどうしましょうか?来園時に呼び出すwelcomeメソッドを作って、welcomeメソッドが呼び出されるごとにカウントアップするようにしましょう。どうぶつごと(インスタンスごと)の来園回数なので、これもインスタンス変数とするのがよさそうです。変数名はcountにしておきましょう。
「来園時の人数」は、来園するときの人数なのでwelcomeメソッドを呼び出すときに指定することにしましょう。来園回数や来園時の人数などは履歴もみたいので、これを管理するメソッドも必要です。来園回数・来園日時・来園時の人数を記録することにしましょう。記録する仕組みをadd_visitメソッドとして、実際の履歴はどうぶつごと(インスタンスごと)となるのでインスタンス変数としましょう。
整理しておきましょう。
クラス変数とインスタンス変数の定義
ではまず変数から定義していきましょう。クラスの名前はAnimalでクラス変数numberとインスタンス変数number, name, age, count,visit_historyを定義しましょう。
class Animal:
number=0
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
self.count=0
self.number=Animal.number
self.visit_history=[]
Animal.number+=1
クラスはclassキーワードで定義するのでしたね。そしてクラス変数はクラスのトップレベルで定義します。一方、インスタンス変数は__init__の中で定義すればよいので上記のようになります。
来園回数はインスタンスが作られたときに初期値0をセットするようにして、welcomeメソッドが呼ばれるたびにカウントアップするようにします。
またクラス変数のnumberは初期値0をセットして、初期化メソッド__init__が呼ばれるたびにカウントアップするようにしましょう。これは「Animal.number += 1」の部分で実現しています。__init__内でインスタンス変数numberにその時のクラス変数の値で初期値をセットするようにすると、初期化メソッドが呼ばれるごとにカウントアップされる会員Noとすることができます。
来園履歴を管理するvisit_historyは__init__では空のリストで初期化しておきます。ここまでは簡単ですね。次にメソッドの定義にうつりましょう。
メソッドの定義
welcomeメソッド
次にwelcomeメソッドを作っていきましょう。来園するたびに呼ばれるメソッドなので、まずは「どうぶつえんへようこそ」という表示をして、来園回数をカウントアップすることにしましょう。続いて、会員No、名前、来園回数を表示することにします。早速、やってみましょう。
def welcome(self,number):
print('どうぶつえんへようこそ')
self.count+=1
print(f'会員No:{self.number} {self.name}さんは{self.count}回目の来場です。')
これでOKです。実際は、来園履歴を管理したいので、来園するたび(welcomeメソッドが呼ばれるたび)に来園履歴を書き込む必要があります。なので、まだadd_visitメソッドを作っていませんが、welcomeメソッドの最後でadd_visitメソッドを呼び出しておくとよいでしょう。この部分はあとから修正することにしましょう。
add_visitメソッド
来園履歴を書き込むメソッドです。来園履歴はインスタンス変数としてvisit_historyというリストを用意しているのでここに書き込むようにしましょう。どんな情報があればよいか、を決めていく必要があります。ここでは、「来園回数」「来園日時」「来園時の人数」を記録することにしましょう。
「来園回数」は既にインスタンス変数countで定義されていますね。「来園日時」はこのメソッドが呼ばれたときの時刻を記録するようにしましょう。「来園時の人数」はこのメソッドを呼ぶときの引数で受け取ることにします。
def add_visit(self,number):
visit={
'来園回数':self.count,
'来場日時':self.get_time_str(),
'来園人数':number
}
self.visit_history.append(visit)
一回の来園の情報を辞書型の変数visitに格納して、これをvisit_historyにappendすればよいですね。来園日時については、あらたにメソッドget_time_str()を定義してこれを呼び出すことにしています。これを追加メソッドとして考えることにしましょう。
追加のメソッドを定義する
get_time_strメソッド
来園日時を取得するメソッドは、クラスの情報を使うわけでもインスタンスの情報を使うわけでもないので、スタティックメソッドで書くことにしましょう。スタティックメソッドは@staticmethodというデコレータを使って定義するのでしたね。
現在時刻はtimeモジュールをインポートして、time.localtime()で取得することができます。
@staticmethod
def get_time_str():
current_time=time.localtime()
return '{0.tm_year}年{0.tm_mon}月{0.tm_mday}日{0.tm_hour}時{0.tm_min}分'.format(current_time)
作成したクラスを試す
ここまで作ってきたAnimalクラスを使っていくつかのインスタンスを作って試してみることにしましょう。まずはrionというインスタンスとcatというインスタンスを作ることにします。
# らいおんとねこのインスタンスを作成
rion=Animal('らいおん',32,52)
cat=Animal('ねこ',34,41)
# 来園する(らいおんが3回、ねこが2回とします)
rion.welcome(2)
rion.welcome(4)
rion.welcome(1)
print('')
cat.welcome(3)
cat.welcome(2)
らいおんとねこのインスタンスを作りました。らいおんは会員No.0、ねこは会員No.1と採番できてますね。この会員Noは何回来園しても変わりません。次にお名前と来場回数もらいおんの場合は1回から3回の来場、猫の場合は1~2回の来場がちゃんと表示されていますね。うまくいってそうです。
では、来園履歴をみてみましょう。インスタンス変数visit_historyがあるのでこれをみてみましょう。
rion.visit_history
これもうまくできてそうです。ただ、この来園履歴を少しみづらいですね。来園履歴をみるためのshow_visit_historyメソッドを作ることにしましょう。
さらにメソッドを追加する
来園履歴はどうやったら見やすくなるでしょうか?来園履歴はリスト型でデータが格納されていて、リストの要素は辞書型で「来園回数」「来園日時」「来園時刻」「来園人数」が記録されています。
リストを順番に取り出すと、来園ごとのデータが取り出せます。さらに1回の来園のデータは辞書型なので、itemsメソッドでkeyとvalueをセットでforループを回せば取り出せそうです。取り出したデータを見やすく成形するところまでやってみましょう。
def show_visit_history(self):
for visit in self.visit_history:
visit_list=[]
for k,v in visit.items():
visit_list.append(f'{k}: {v}')
print(', '.join(visit_list))
取り出したデータをリストに格納して、joinメソッドでつなぎ合わせることで成形しています。これで見やすいデータとなるはずです。やってみましょう。
rion.show_visit_history()
見やすいデータになりましたね。
まとめ
今回は実際にクラスを作成してみてみました。はじめは、抽象的な要件からはじめて実際にコードを書くにあたり少しずつ具体化していく過程も体験できましたね。
コメント