Pythonを始めて一通り、コードの書き方は分かってきた。
次なる壁はclassの習得だけど、、、だめだ、、、わからん。という方は結構多いのではないでしょうか。
私がまさにそうでした。
解説しているサイトを見ても、正直全く分かった気がするだけだし、プログラミングができる人に聞いたとして、分かりやすく説明しようとしてくれているんだろうけど。
残念ながら、まったくその説明自体が理解できない(涙)
特にオブジェクト指向については、分からない人は全く概念が理解できていないので、何が分からないのかも分からない人に説明するのってすごく難しいですよね。
そんなこんなで私は約半年、Pythonの勉強がストップしていました。
それが、、突然先日理解できたのです。まるで何かが降りてきたように。
そこで、是非同じ境遇の方、またはこれからオブジェクト指向という概念を理解しようと人が自分と同じ目に合わないよう、順を追って何回かに分けて解説していきます。
なお、この記事で説明するにあたり登場する基本的なコードの書き方に関する過去記事を掲載しますので怪しい方は、後で復習しておくとよいと思います。
・変数について➀
・変数について➁
・if分(条件式)
・リストとランダムモジュール、条件式(じゃんけんプログラム)
目次
オブジェクト指向って難しい?どうやったら簡単に理解できる?
オブジェクト指向を完全にまるっと、一部の隙もなく理解しよう。それは相当難しいかもしれません。
私も、まずは理解しないと先に進めないだろうと、あれこれ本を読み・サイトで調べ・エンジニアの方や詳しそうな方に聞きまくりました。
しかし、結果からいうとそれで理解はできませんでした。
分かると分からないの差があまりに大きく、少しでも分かり始めればそれはほとんど理解したに等しい状態となります。
つまり、数式やコードを覚えるような習得の仕方でなく、概念を理解、むしろ実践してみてその感覚を理解するという行為が習得に繋がります。(そこに行きつくまでにどれだけ時間がかかったか・・・)
そういうものなんで、どんなに分かっている人でもなかなか分からない人に”説明する”ことは難しいわけです。
ここで、その概念をまず記載します。オブジェクト指向とは・・・
プログラム上で疑似的に”もの”を作り出すことだと私は理解しています。
プログラム上の疑似的な”もの”とは?
いよいよ分からなくなってきました?(笑)
「プログラム上の疑似的な”もの”」とか、抽象的な書き方をしやがってと。
お怒りはごもっともです。
では、実際にプログラム上に疑似的な”もの”を作り出す過程を、一緒に辿りながら考察していきましょう。
「おみくじ」という”もの”をプログラム上で再現してみよう
「おみくじ」という”もの”はどういうものでしょうか?
そんなの改めて説明しなくても分かるでしょ!と思う方も多いと思いますが、当たり前のことを言葉で定義していくって実は結構難しい作業です。
そして、”もの”の要素をどのように分解してとらえ、それぞれどんな機能が最低限あれば、その”もの”として再現が可能か
。この考え方こそが、オブジェクトを作るという行為ではないかと思っています。
では、「おみくじ」の要素を分解して、言葉でそれぞれ要素ごとの機能を定義していってみましょう。
・四角い箱にたくさんのくじが入っている
・くじには大吉・吉・凶などが書かれている
・くじには願い事が叶うか・恋が成就するか等の占い的なものも書かれている
・100円程度を払うとおみくじができる
・四角い箱の真ん中に丸い穴が開いていて、手を突っ込んで1枚くじを引く
・引いた結果が大吉だったら、気に結び付ける(吉とかでも結ぶ??)
大体以上の要素があれば、間違いなくおみくじといえるでしょう。
「おみくじ」の要素をどこまで再現するか考える
上記にあげた要素は一旦フルセットだと考えてください。
では、この要素はなくとも「おみくじ」の体裁は保てるのではないか?というものはないでしょうか。
例えば、100円は払っても払わなくても、どっちでもいいですよね(神社としてはそうではないでしょうが)
このように、要素のどの部分は必要、またどの部分は不要。あるいは目的に応じて、フルセット必要など。
どこまで「おみくじ」を再現するかということを考えるのも、オブジェクト指向だと考えています。
「おみくじ」をどう再現するかを考える(要素の検討)
では、再現度に応じて松案・竹案・梅案をそれぞれ考えてみましょう。
・四角い箱にたくさんのくじが入っている
・くじには大吉・吉・凶などが書かれている
・くじには願い事が可能か・恋が成就するか等の占いも書かれている
〔対応案〕
☞「おみくじ」としての最低限の体裁を保てるレベルとして、
大吉・中吉・末吉・吉・凶・大凶と6種類くじを作成する(要素 ➀)
・100円を程度払うとおみくじができる
〔対応案〕
☞ 100円と文字列を入力したら、100円払ったものとしてくじが引かれる(要素 ➁)
・四角い箱の真ん中に丸い穴が開いていて、手を突っ込んで1枚くじを引く
〔対応案〕
☞ 6種類のくじから1種類がランダムで引かれるようにする(要素 ➂)
・引いた結果が大吉だったら、木に結び付ける
☞ くじの結果と結果に応じたメッセージを表示する(要素 ➃)
さらに大きな”もの”の再現の仕方を考えてみる
プログラム上で疑似的に”もの”を再現することについて、なんとなくでもイメージが沸きましたか?
では、もっと大きなものを再現することをイメージしてみましょう。
おみくじは神社にありますよね?
では、神社を再現する方法を考えてみましょう。
神社にある要素として、鳥居があります。お賽銭箱があって、本坪鈴(※)があって、鈴緒(※)があって・・・
神主さんがいて、巫女さんがいて・・・
これら一つ一つを”もの”として、再現する際におみくじのように必要を要素を備えたオブジェクトとして、
作成をするイメージです。
仮に、それぞれ一つ一つプログラムを書いていったとして、もう一つ神社を作りたくなった場合に、
一つ一つの要素がオブジェクトとして作成されていれば、それを流用してちょっと違いを出したい部分だけ、
アレンジできるのです。
また、環境が変わってキャッシュレス化に合わせて、お賽銭をLinepayでQR決済で払うなんて仕様変更を
したい時にも共通部品としてお賽銭箱をつくっていれば一回の改修が全ての賽銭箱に反映します。
仮に400個の神社があって、400個のお賽銭箱を一個一個直していくのは・・・苦痛でしかないですよね(笑)
一つ一つの”もの”を共通で使えるように部品化しておくことは、保守性の向上にもつながるわけです。
classとは?おみくじという”もの”をPythonで再現してみよう
今までの話を踏まえて、やっとこさclassについて触りをお話しします。
前項で記載した”神社”や”賽銭箱”、”おみくじ”、”本坪鈴”、”鈴緒”、”神主”、”巫女”さん・・・
これら全てを”もの”として定義する手段として、classがあります。
神社クラスや、おみくじクラスを作っていくわけです。
では、試しに先ほど要素➀~➃を洗い出した「おみくじ」について、実際にPythonでおみくじclassを作成してみましょう。
ユーザーの立場でシステム開発に携わったことがある人は分かると思いますが、いわば要素➀~➃は業務要件です。
この業務要件をそれぞれどのようにシステム設計するかが、システム要件です。
☞「おみくじ」としての最低限の体裁を保てるレベルとして、
大吉・中吉・末吉・吉・凶・大凶と6種類くじを作成する(要素 ➀)
➡システム要件 ➀
cards変数にリスト型でくじの結果を格納し、おみくじclassに持たせておく。
☞ 100円と文字列を入力したら、100円払ったものとしてくじが引かれる(要素 ➁)
➡システム要件 ➁
input関数で100円を文字列で入力させ、100円入ったらくじが引かれるようにする
start変数で100円を受け取り、if分で条件分岐をつくり、start変数が100円である場合は後続の処理にすすむ
start変数が100円以外である場合は、elseで例外処理として受けて100円を入れるようメッセージを返す
☞ 6種類のくじから1種類がランダムで引かれるようにする(要素 ➂)
➡システム要件 ➂
おみくじclassにくじを引く、omikuji_choiceメソッド用意する
omikuji_choiceメソッドでは、randomモジュールを使って用意したcards変数に格納されている
おみくじの結果からランダムで一つを抽出。抽出した結果をchoose変数に格納する
☞ くじの結果と結果に応じたメッセージを表示する(要素 ➃)
➡システム要件 ➃
引いたくじの結果に応じif分の条件分岐で、出力する結果・コメントを分けてreturnで返す。
choose変数に値が格納されなかった場合(プログラムがおかしい)はエラーと返すようにする。
最後に上記システム要件をもとに書いたコードと、実行結果は以下のとおりです。
次回は、もっと踏み込んでclassの書き方を解説していきます。
ご自分でも、何かプログラムで再現できそうなオブジェクトがないか考えてみてください。
おみくじclassのコード例
・Pythonで作成したコード例
・実行時のコード
作成したomikuji.pyファイルをimportし、変数oにOmikujiクラスを代入。
omikuji_choiceメソッドを実行。
・実行時に入力を求められる
・10円と入れた場合の出力結果
100円を入れてくださいと出力されてますね
・100円を入れた場合の出力結果
くじの結果と結果に応じたメッセージが表示されます