こんにちわ!この記事はPythonの初学者のための内容となっております。
今回もオブジェクト指向についての内容ですが、その目的は、
- オブジェクト指向についてより詳しく知りたい
- まだ理解が浅い
- 関数の使い方の復習もしたい(キーワード指定引数、可変長引数)
という方向けの内容となっております。
また、基本的なオブジェクト指向の考え方などについて知りたい方は前回の記事を参照してみてください。
前回の記事
それでは頑張っていこう!
プログラミングスクールに関しては下の記事で詳しく記述しています。
こちらで紹介しているスクールは、すべて無料期間がある優良なスクールのみで、特徴を明確にし、読者のニーズに絞って丁寧に解説しました。初めての一歩として、無料説明会に参加してみてください。
コンテンツ
オブジェクト指向のおさらい
基本的な性質と概念
オブジェクト指向とは、人間がプログラムを組むうえで大規模になったときにも考えやすいようにするための概念でした。値やデータを一つのオブジェクトとして扱うこと、つまり、プロセス指向ではない方法でプログラミングをすることで、オブジェクト指向は、プログラマーフレンドリーな記述方法でした。
オブジェクト指向型プログラミングを行う際に重要なキーワードは、「コンストラクタ」、「インスタンス」、「メンバ変数」などたくさんありました。また、クラスが最初に呼び出されたとき一度だけ呼び出される関数は「 __init__ 」でしたね!
コードでたくさん出てくる「self」とは、オブジェクト自身の性質や変数を表現する予約語でした。この辺りを理解していれば大丈夫です。復習として実際のコードを見ていきましょう!
頑張っていこう!
コードの書き方
今回は「Fruits」クラスを定義するよ!
1 2 3 4 5 6 7 8 9 10 11 |
class Fruits: def __init__(self, name, num, g): self.name = name self.num = num self.g = g def calc_weight(self): weight = self.num * self.g print(self.name + str(self.num) + "個で" + str(weight) + "gです。") return weight |
続いて「main」関数!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if __name__ == "__main__": #インスタンスの生成 apple = Fruits("リンゴ", 5, 500) #各メンバ変数の参照 print(apple.name) #リンゴ print(apple.num) #5 print(apple.g) #500 #関数の利用 print(apple.calc_weight()) #リンゴ5個で2500gです。 #2500 |
コンストラクタの引数は「name」、「num」、「g」の3つで受け取った引数をメンバ変数に代入しているのがわかりますね!これによって、各オブジェクトの性質を参照することが可能になりました。
また、メンバ変数を参照するためによく使う関数として、次のセッターメソッドとゲッターメソッドがあります。これらははぼ関数名が固定されているので他のプログラマに見てもらうときにも非常にわかりやすく説明ができます!
セッターメソッドとゲッターメソッド
オブジェクト指向のおさらいの項目に入っていますが、実はまだ手を付けていませんでした。セッターメソッドとゲッターメソッドの使い方をいていきましょう!
もう一度「Fruits」クラスを再定義するよ!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class Fruits: def __init__(self): self.name = "" self.num = 0 self.g = 0 def setName(self, name): self.name = name def setNum(self, num): self.num = num def setG(self, g): self.g = g def getName(self): return self.name def getNum(self): return self.num def getG(self): return self.g def calc_weight(self): weight = self.num * self.g print(self.name + str(self.num) + "個で" + str(weight) + "gです。") return weight |
続いて「main」関数!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
if __name__ == "__main__": apple = Fruits() apple.setName("リンゴ") apple.setNum(5) apple.setG(500) print(apple.getName()) #リンゴ print(apple.getNum()) #5 print(apple.getG()) #500 print(apple.calc_weight()) #リンゴ5個で2500gです。 #2500 |
「コード長っ!!」って思った方多いのではないのでしょうか?長いんです笑。
ただ、「set〇〇」、「get〇〇」と統一することによって誰が見ても一目瞭然で分かりやすいコードにはなります。メンバ変数が増えれば増えるほどこれらのメソッドが多くなっていきます。
こういったメソッドを利用しないで、一気に代入する方法が前回やったコンストラクタを用いた記述方法でした。コンストラクタとセッターはプログラム的には同じ処理をしています。
じゃあコンストラクタとセッターどちらを用いるべきなの!?
僕の回答としては、名前など、今後変わる予定のない変数に関しては、インスタンスを生成した時にメンバ変数を代入する。つまり、コンストラクタを用いて処理をすれば、記述漏れや忘れなどがなくなりいいと思います。一方で、今後変わる予定の個数や重さなどは後からいくらでも再設定できるようにセッターを用いるのがベストかなと思います。
個人的見解を発表してもうた!(違ったら教えてください_(._.)_)
様々なインスタンス生成方法
複数のインスタンス
一番最初の「Fruits」クラスをそのまま利用します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import random if __name__ == "__main__": #果物の名称とその重さ fruits = {"リンゴ" : 500, "バナナ" : 800, "サクランボ" : 100} sum = 0 for key, value in fruits.items(): num = random.randint(1, 5) f = Fruits(key, num, value) sum += f.calc_weight() print("合計" + str(sum) + "g" + "です。") """ リンゴ5個で2500gです。 バナナ4個で3200gです。 サクランボ5個で500gです。 合計6200gです。 """ |
「for」文の中で変数「f」に生成されたオブジェクトが代入されています。
次に、変数「sum」へオブジェクトの重さが返り値として代入されています。この時関数の中で文字列の出力もされているのがわかりますね!最終的に各オブジェクトの重さを足し合わせた値が結果として出ています。
いけるゾ!
辞書型配列の使い方の不明点がある場合は過去の記事を参照してみてください!
過去の記事
キーワード引数の利用
キーワード引数を用いたインスタンス生成方法を見ていきましょう!
キーワード引数の基本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
class Human: def __init__(self, name = "名無し", gender = "中"): self.name = name self.gender = gender def introduce(self): print(self.name + "さんは" + self.gender + "性です。") p1 = Human() p1.introduce() #名無しさんは中性です。 p2 = Human(name = "山田") p2.introduce() #山田さんは中性です。 p3 = Human(gender = "男") p3.introduce() #名無しさんは男性です。 p4 = Human("太郎", "女") p4.introduce() #太郎さんは女性です。 |
「Human」クラスのコンストラクタの引数は2つ準備されていますが、生成したインスタンスは0個から2個とバラバラです。しかし、「name」にはデフォルト値として、「名無し」が、「gender」には「中」が最初から設定しているため、引数が足りなかったらデフォルト値でメンバ変数を代入することが出来ます。また、どちらかのみを設定したい場合は、引数の名前を指定すれば柔軟に記述できます。便利でしょ!
この辺の詳しい内容に関してはまた別の記事で書きたいと思います。
キーワード引数を用いたインスタンス生成
先ほどの内容を理解していただけたら次のコード例は難しくないはずです!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class Fruits: def __init__(self, name, taste = "甘ぇ"): self.name = name self.taste = taste def taste_introduce(self): print(self.name + "は" + self.taste + "よ!") if __name__ == "__main__": fruits = ["リンゴ", "バナナ", "サクランボ"] sour_fruits = ["レモン", "キウイ", "ブドウ"] for fruit in (fruits + sour_fruits): if fruit in fruits: f = Fruits(fruit) else: f = Fruits(fruit, "酸っぺぇ") f.taste_introduce() """ リンゴは甘ぇよ! バナナは甘ぇよ! サクランボは甘ぇよ! レモンは酸っぺぇよ! キウイは酸っぺぇよ! ブドウは酸っぺぇよ! """ |
あまり良い例ではないかもしれないのはご了承ください。
理解できたから良き!
まとめ
今回は、オブジェクト指向を前回よりも詳しく記述してみました。コンストラクタとセッター、ゲッターメソッドの使い分けや、キーワード引数を用いることによって、インスタンスの生成の仕方にバリエーションが生まれることがわかりました。また、たくさんのインスタンス生成方法や基本的なオブジェクト指向についてもご理解いただけたと思います。
しかし、まだまだオブジェクト指向はたくさんの概念が存在していて、全然紹介しきれていません。次回も頑張っていきましょう!
本日の理解度調査
今日の最後に理解度調査をします!!
どうすれば正しくなるのか考えてみてね!!
Q.トランプ52枚(4種×13枚)をインスタンス生成せよ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
class Card: def __init__(self, mark = "", number = 0): self.mark = mark self.number = number if __name__ == "__main__": marks = ["H", "D", "C", "S"] cards = [] for mark in marks: kind = "" for i in range(1, 14): c = ??? kind += c.mark + str(c.number) + " " #最後の空白を除去するため「kind[:-1]」 cards.append(kind[:-1]) #2次元配列を順番に表示 for kind in cards: print(kind) """ H1 H2 H3 H4 H5 H6 H7 H8 H9 H10 H11 H12 H13 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13 C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 S1 S2 S3 S4 S5 S6 S7 S8 S9 S10 S11 S12 S13 """ |
正解は。。。
1 2 3 |
for i in range(1, 14): c = Card(mark, i) kind += c.mark + str(c.number) + " " |
わかったかな??正解出来たら今回の項目は完璧だね!!
最後まで記事を読んでいただきありがとうございます!
プログラミングスクールに関しては下の記事で詳しく記述しています。
こちらで紹介しているスクールは、すべて無料期間がある優良なスクールのみで、特徴を明確にし、読者のニーズに絞って丁寧に解説しました。初めての一歩として、無料説明会に参加してみてください。