50歳からの人生 自分の好きなことやって生きていくことができるのか!? ここは「がっちゃん 」が実際に体験したことを記録し、楽しく人生を過ごせるためのヒントをさぐる研究所です!

Pythonプログラミングレッスン:その3(クラス)

 どうも! 職業訓練生のがっちゃんです!

 50歳にして長期人材育成「情報セキュリティ管理者資格」2年コースを絶賛受講中です!

 今回は、授業で習った「Python3系」プログラミングの基礎:クラス編として書いていきたいと思います。

 プログラミングで使用したソフトは「Anaconda」というパッケージソフトの「Anaconda Prompt」というアプリを使って勉強しました。

classって、なんぞ!?

 Pythonが、組み込みで提供しているさまざまな型はクラスです。例えば、以下のコードを実行してみればわかります。

 実行結果は、以下のとおり。それぞれ、<class ‘str’> や <class ‘int’> と表示されます。

 この「class」というのが、文字列’a’の型は「strクラス」、整数7の型は「intクラス」ということを表している。「文字列’a’はstrクラスのオブジェクト」であり「整数7はintクラスのオブジェクト」となる。オブジェクトとは、プログラムを実行したときに作成されるデータ(実体)のことをいう。これに対して「class」とは「オブジェクトを作るための設計図」と言えます。

 オブジェクトのことを「あるクラスの設計図から作り出された実体」であることを言うために「インスタンス」ということもある。

 例えば、int型は「整数という概念を記述した型(クラス)」であり、整数値「7」は「整数という概念をもとに作り出された具体的な値(インスタンス)」であるといえます。

 そして、プログラマーが、そうした型(クラス)を独自に作り出すこともできます。そのために使うのが「class」と呼ばれるものです。

turtleクラスを体験する

 Pythonには「turtle class」というものがあって、一定の広場で亀さんを動かすことができるクラス(設計図)があります。あなたは「コマンドプロンプト」から、その亀に対してアチコチと歩き回らせることができる。

 基本的な命令として「○○歩前進せよ」「○○歩後退せよ」「××度右(左)に回転せよ」がある。さらに亀さんはペンを持っていて「ペンを下げる」「ペンを上げる」ことも可能である。亀さんの色や形を変更したりすることもできる。亀さんを増やすこともOK。

 これらを使って楽しみながら「クラス」や「インスタンス」について理解を深めようという魂胆である。

操作方法

 今までは「Spyder」というソフトを使っていましたが、このタートルクラスは、とっても相性が悪いようで、使うとすぐにフリーズしてしまうのでご注意ください。今回は「Anaconda」というパッケージソフトの中にある「Anaconda Prompt」というアプリを使ってください。Macの方は「Qt Console」というのをお使いください。


 操作コードはざっと以下のとおり。まずは「import turtle」で、タートルモジュールを呼び出します。

 実際のコードと実行結果はこんな感じです。同じコマンドを何度も書くのは大変なので「↑」「↓」キーで、一度入力したコマンドは呼び出すようにしましょう。

 その他、授業で教えてもらったコードは以下のとおりです。色々と実行してお楽しみください。

 Pythonの公式ページにいろいろなコマンドが掲載されていますので、こちらもご参考にどうぞ。

クラスを作ってみる

 Pythonでのクラスの基本的な書き方は、以下のとおりになります。

 クラスの中のメソッドには「self」というものが存在します。このselfは、インスタンス自身(具体的な値、実体)を示すものです。また、selfはpythonの設計仕様で欠かすことはできません。名前を self 以外のキーワードにすることは可能ですが、慣例として self を使用します。Pythonでは作成されたコードを他人でも一眼で分かるように書くことが重要です。そのため、基本的には self としておくほうが良いと思います。

 実行してみると、以下のとおりになります。

 ちなみに「 m = Employee() 」とインスタンス化せずに、そのまま Employee を使ってみましょう。

 そうすると、print(Employee.name)はうまくいきましたが、Employee.work()のところでエラーが出ちゃいます。エラーの文面を見ると、「selfに対する引数が必要だけど足りてないよ!」と言われているみたいです。

 

 というわけで、引数「’今日は日曜日なのに仕事って、マジっすか!?’」を入れて作成してみました。これだけだと、この引数はどこにも反映されそうにないのでにprint文に self を足してみました。

 実行結果は以下のとおり。エラーは出なくなりました。

 エラーは出なくなったけど、本来、クラスはインスタンス化して使うものですので、キチンとインスタンス化して使うようにしましょう。でも、これはこれで、クラスのまま呼び出したい時に使えそうな技ですね。

※追記:あとで分かったのですが、クラスを定義しただけでもインスタンスは生成されているそうです。でも、インスタンスは1つしか生成できないので、2つ目を生成しようとするとエラーになるそうです。

 そんなわけで、次も、こんな処理方法もあるんだなという感じでやってみましょう。

 実行結果は以下のとおりです。名前の変更とかも簡単にできちゃいますね。

コンストラクタの作成

 コンストラクタとは、「__init__」の部分のことです。インスタンスを作成する際に重要な処理を行うものです。どのように生成するか、どのようなデータを持たせるかなど、情報を定義するのに必要なメソッドです。

 第1引数「 self 」は、インスタンス自身を指します。Pythonの慣習として名前は「 self 」で指定します。「 self 」は呼び出し側では指定は不要で、2番目の引数以降を指定します。

 まずは、デフォルトで引数に何も設定しないプログラムになります。

 プログラムの実行結果がこちらになります。

 続いては、デフォルトで引数を設定した場合です。他にもちょっといろいろ変更してみました。

 実行結果はこんな感じです。デフォルト引数を設定しておけば、関数を呼び出すときに、その引数を省略することができます。また、その逆で関数を呼び出すときに「デフォルト引数=設定したい値」と書けば、デフォルト値以外の値を設定することができます。

 現状、このようなデフォルトの引数設定は「オン・オフ」の機能設定などで使われていることが多いそうです。

 work関数に引数 place をつけて作ってみました。

 実行結果はこんな感じ。色々と自分で機能を追加したりしていくと、どんな感じで動くのか理解できるようになりますね。

継承

 継承は、クラスの中でよく使われる機能で、作成済みのクラスを再利用したり、機能を追加したりできる、とても便利な機能です。継承元を「親クラス」、継承先を「子クラス」と呼び、「子クラス」は「親クラス」の性質(メソッドなど)を引き継ぐことができます。

 一般的には、抽象性や汎用性が高いものを「親クラス」、具体性が高いものを「子クラス」として表します。

 実行結果は以下のとおりになります。各「Renpougun」「Zeon」クラスにはpassしか書かれていませんが、親クラスの値やメソッドを継承していることがわかります。

 「親クラス」「子クラス」に同じメソッドがあると、子クラスのメソッドが優先して実行されます。

 で、実行結果はご覧のとおり。子クラスのメソッドが優先されて実行されています。

superで親クラスを継承

 「子クラス」が「親クラス」の機能を継承するのに「super()」を使って「親クラス」の機能を呼び出すことができます。

 実行結果はこんな感じ。「super().intro()」だけで親クラスの「intro関数」を使えるようになりましたね。

カプセル化

 プログラムの、外部からの操作を制御し、プログラムの独立性を保つための仕組みです。呼び出しを制限することで、ミスを防いだり、プログラムを読みやすいものにすることができます。

 pythonでは、クラスからインスタンスが作られるときに、変数に値が渡されます。このインスタンス変数は、今までのプログラムでもそうでしたが、簡単に書き換えることができます(例:「比企谷八幡くん」を「ひきがやはちまんくん」に変更した件や、「山田太郎さん」を「佐藤B作さん」に変更した件)。

 公式ドキュメントでも「データ隠蔽を補強するための機能は何もありません」と記述されており、基本的にすべてのデータやメソッドは外部に公開されており、プライベートなデータやメソッドは存在しません。その代わり、慣習的な命名規則として「__」(アンダーバー)から始まる変数名やメソッド名は、プライベートとみなします。

 プログラムの実行結果は以下のとおりです。「myname」はカプセル化されていないので、直接書き換えることが可能ですが、「__mymoney」はカプセル化されているので、直接書き換えることはできません。

エラーオブジェクト

 プログラムの処理中にエラーが発生した時、強制的にプログラムが終了されないよう「エラーハンドリング」と言って、あらかじめエラー発生に備えて、エラーを察知してこちらで準備したエラ〜メッセージを出すようにし、プログラムを強制終了させないようにすることです。

 以下のプログラムのままだと、入力値によってはエラーが出てプログラムが強制終了になってしまいます。

 こんなふうにキチンと割り切れる数字を入力すれば良いのですが、

 わざとこんな数字を入れようものなら、エラーが出てプログラムが強制終了されてしまいます。

 と、こんなふうにプログラムが強制終了されないように「try except」でエラーキャッチができるようにします。

 こうすることで、以下のようにエラーをつかまえて、準備したエラーメッセージをプリントすることができます。これにより、エラーが出ても、プログラムの最初に戻って実行させることも可能になります(while文とか使って、プログラムの最初に戻るように書かないとダメっすけどね)。

以前作成した「抜けているアルファベットを当てるプログラム」をクラス化してみる

 Pythonプログラミングの基礎:その2の最後の練習問題で作成した「抜けているアルファベットを当てるプログラム」を、クラス化していきます。そのプログラムが掲載されているブログリンクを以下に貼っておきますので、ご参考にどうぞ。

その前に「回答にかかった時間を計測」する機能を追加

 難易度を高めて作成したプログラムに、時間軸を取り入れて、回答にかかった時間を計測できるようにします。これで回答時間が一番早いのは誰かを競えるようになり、ゲーム性が一段と高められますね。

 先日作成した「mojiate5.py」を、以下のように修正します。「mojiate5_module.py」は変更ありませんので、そのまま流用します。

※「mojiate5_module.py」のプログラムは、「Pythonプログラミングの基礎:その2(関数)」のブログをご参照ください。

 実行結果は以下のとおりです。キチンと時間表示ができましたね。

 これが完成版ですが、「datetime.datetime.now()」がどんな数字を取ってきているのかを確認するためにも、print文を一度「print( t2 – t1 )」にして実行してみてください。

時間計測するタイマークラスと入出力クラスの作成

 時間を計測するためのストップウオッチ機能のクラス化と入出力系の機能をクラス化を行います。以下「mojiate6.py」を修正して「mojiate7.py」にして進化させました!

※注意:プログラムを実行した際、「なんか分からんけどエラー出る。引数とか間違ってないねんけどなぁ」というあなた!インデントが正しいかをまず疑いましょう。プログラミング専用のソフトで作成するとたいていのエラーは事前に知らせてくれるのですが、インデントだけは「間違ってるで!」って知らせてくれないので、まずはこれを疑いましょう。

 上のプログラムを実行して問題なければ、Timerクラスを「timer_module.py」ファイルに、SystemIOクラスを「systemio_module.py」ファイルに分けていきます。

 これにより「mojiate7.py」のプログラムがとても見通し良くなります。

 2つのクラスをモジュール化することにより「mojiate7.py」は以下のように見通しがよくなりました。

 実行結果は以下のとおりです。それぞれのモジュールが呼び出されていることが分かりますね。どうでもいいけど、何べんやっても20秒の壁が破れんわ。

仕上げに「mojiate5_module.py」にある「print文」を無くしたい

 せっかく「systemio_module.py」を作ったので、「mojiate5_module.py」にある以下2カ所の「print文」も無くしたいところ。

 私は以下のように「SystemIO()」インスタンスの2つめを作って書いてみたのですが、あまり好ましくない対応だそうです。

 しかも実行したら、なんだか先ほどと違って「enter」キー何回も押さないと次へと実行しない。ゲームがモタモタしてる。

 引数「io」を入れてあげるだけで、「io」インスタンスを使いまわせるという、取ってもシンプルで分かりやす回答を教えてくださいました。以下、修正した「mojiate5_module.py」と「mojiate7.py」になります。「timer_module.py」と「systemio_module.py」は変更なしです。

 出来上がったら最終チェック。実行してみましょう。

 バッチリですね。先ほどのモタツキ感もなくなりました。関係ないけど、とうとう回答時間20秒の壁を突破しました!個人的にはなんか嬉しい。

まとめ

 Pythonの授業は、ゆっくりと進めてくれているうえに基本構文からの学習なので、とても分かりやすいなぁ、と感じています。プログラム見ただけで、だいたいどんなことが書かれているのかが分かるのも、関係あるのでしょう。

 プログラミング超シロウトの私が言うのですから、間違い無いんじゃないでしょうか!?いよいよ基本情報処理技術者試験のプログラミングの選択は「Python」が有力になってきました!

それでは本日も最後までお付き合いいただき、ありがとうございました!

スポンサーリンク
最新情報をチェックしよう!