プログラミングのオンライン実行環境であるpaiza.ioを使っています。今回はPython3で型・クラス・オブジェクトなどの整理をしてみます。大きなテーマとしては、非オブジェクト指向言語とオブジェクト指向言語の考え方の導入部分ですが、オブジェクト指向言語の分かりにくくなりがちな用語の長い説明はしません。
Python3でpaiza.ioで実際に動作させながら書きます。多少強引で無理な書き方になる部分もあるかと思いますが、「オブジェクト指向が全然分からないからプログラムを勉強するのをやめる」というのをぜひやめて欲しいと思うので、その考え方で書きます。(※学術的な正確さが必要な場合や試験対策等は他のサイト、書籍等を参照して下さい。)
非オブジェクト指向言語とオブジェクト指向言語
ここでは単純にオブジェクト指向の概念を仕様として持っていないプログラミング言語を非オブジェクト指向言語(手続き型言語や構造化プログラミング言語という言い方も出来ます。)とします。
そうすると分かりやすいと思ったのがC言語、C++です。C言語が非オブジェクト指向言語でC言語にオブジェクト指向の概念を追加した言語がC++です。C言語には言語の仕様として変数、型、関数の概念はありますが、言語の仕様にはクラス、オブジェクト、メソッド等のオブジェクト指向の概念はありません。(以下のようにC言語ではclassという変数名が普通に使えます。)
他にはC#やJavaもオブジェクト指向言語に分類されます。これらも言語の仕様としてクラス、オブジェクト、メソッド等のオブジェクト指向の概念があります。(単純な変数名としてclassはもちろん使えません。)
但しですが、オブジェクト指向言語でも、変数、型、関数という表現もしますし、例えばC++ではC言語の仕様でもプログラミングが出来ます。
オブジェクト指向言語のメリット
それでは、なぜオブジェクト指向言語で開発するのかというと例えば以下のようなメリットが期待出来るからです。
追加、変更などのメンテナンスが簡単(余計な修正作業や間違いが少なくなる)
拡張性が高い
独立性が高い(分業がやりやすい)
C++が普及して、そのあとJavaが登場して普及した頃(2000年代ぐらいだったと思います。)は、「いかに正しいオブジェクト指向で開発するか」が重要課題だったと思います。そのため無駄に冗長な仕様ばかり増えて意味もなく複雑化したという失敗もあったかと思います。私自身では、C++で開発されたアプリケーションのカスタマイズ時にドキュメントがないプログラムのソースコードを読んでクラス構成を把握するのにかなり時間が必要だった記憶があります。
今現在は「正しいオブジェクト指向」よりも、上記のような期待出来るメリットをどのように実現するかが大事だと考えられていると思います。もちろんこれがそう簡単ではありませんが。
Python3で考えてみる
それでは、本題となるPython3についてですが、Python3では非オブジェクト指向言語の考え方からオブジェクト指向言語の考え方まで柔軟に対応していていろいろな書き方が出来ます。(このあたりは私自身も好きですし、人気がある理由の一つでもあると思います。)
Python3でプログラミングを習得するためにはまずは非オブジェクト指向言語の考え方(構造化プログラミングの考え方)でプログラミングの勉強をしっかりすればいいと思っています。(※普通はそうしていると思いますが。)
構造化プログラミングについては以下で書きました。
構造化プログラミングについての整理
ここからPython3での型・オブジェクト・クラスを整理してみます。
まず以下は特に意味のある処理はしていませんが見て下さい。
非オブジェクト指向言語の考え方では以下のようになると思います。
変数aを0で初期化した。その時点で変数aは整数型の変数となり、3を足したからその時点で変数のaは3となった。
オブジェクト指向言語の考え方では以下のようになると思います。
変数名aのオブジェクトを0で初期化した。その時点で変数名aのオブジェクトは整数型の変数となり、3を足したからその時点で変数名aのオブジェクトは3になった。
何でわざわざ「オブジェクト」と呼ぶのかまた「オブジェクト」とは何だよとなると思いますが、以下にPython3におけるオブジェクトの説明があります。
Python言語リファレンス 3.1. オブジェクト、値、および型
Python3でのオブジェクトとは「データの抽象的表現(abstraction)」とあります。上記のプログラムの場合は、変数名aの整数データのことです。
整数データに限らず他にもPython3が扱うデータは全て「オブジェクトまたはオブジェクト間の関係」と表現出来るということです。整数データ以外ですが、実数データ、文字列データ、ファイル、ファイルの内容などなどいろいろなデータということです。
Python3ではあまり難しく考えず、まずはPython3で扱うデータは全て「オブジェクト(またはオブジェクト間の関係)」と表現していいということです。
このオブジェクトの種類を「型」と呼んでいます。整数型、実数型、文字列型などなどです。次にこの型について整理してみます。
Python3で型とクラスを考えてみる
上記のプログラムの続きで、Python3のtype関数に変数aを渡してみると以下のように表示されます。
aは、intクラスだと表示されました。実はクラスなのかということです。
ここで、Python3におけるクラスとはですが、以下のPythonチュートリアルから引用すると「クラスはデータと機能を組み合わせる方法を提供します。」となっています。
Pythonチュートリアル クラス
これも「オブジェクトとは」と同様にあまり難しく考えず、まずは「データと機能の組み合わせ」と考えるということです。
さらに、type関数にtype(a)の結果を渡してみます。以下のように表示されました。
aはintクラスであり、intクラスはtypeクラスでもあるということでしょうか。(言語の仕様としてはこのあたりが実はおもしろいところでもあると思っています。)
Pythonでは(オブジェクトの)型という表現をよく使います。実際には型も上記のようにクラスですが、型という表現は非オブジェクト指向言語でも使うので、(オブジェクトの)クラスと表現するより分かりやすいと思いますが、いかがでしょうか。
つまり、○○型といってもクラスなので提供される機能(メソッド)を使えばその○○型のデータが操作出来るということです。このあたりPythonは非常に充実しているのでどんどん使っていけばいいと思います。
int型をクラスらしく書いてみると以下のように書けます。
a = int(0)
a = a + 3
この場合は、整数オブジェクトaをintクラスのコンストラクタで0にインスタンス化して、そのオブジェクトaに3を足したという表現になります。インスタンス化とは実際にコンピュータが動作する環境で処理出来る状態(初期化)にすることです。
Python3で日付型を使ってみる
ということで日付型を使ってみます。
日付型はint等の組み込み型ではなく標準ライブラリになるのでモジュールをimportします。これでdatetime(日付型のクラス)が使えます。ここではnow()を使っています。
出力の表示を見ると、日本時間と違いました。ということでtimezoneを使って日本(Tokyo)を指定します。
日付や時間を別々に使いたいという場合は以下のように各属性(ここでは日付や時間の各要素のこと)を取得出来ます。
このように使い方を覚えて(別に暗記する必要はないです。)自分のプログラムで使っていけばいいです。
この他にも例えば以下のような複数のデータ管理するデータ型があります。これらで複数のデータを操作してみるといいと思います。そうすると、実際にはいろいろなクラスを使うことになります。
リスト、タプル、辞書、集合
以下は関連リンクです。(このシリーズ各回の2ページ目からはユーザ登録が必要になりますが、内容は非常にいいと思います。)
Python入門 リストの基本
あとはファイル操作をやってみるのもいいと思います。ファイルの場合は型という表現よりファイルオブジェクト(つまりデータファイル)という表現の方が分かりやすいと思います。
日付型で練習問題的に
上記のように日本の現在時刻を取得して、朝、昼、晩の時間帯での各あいさつ(おはようございます。こんにちは。こんばんはなど)を表示してみて下さい。
上記日付型操作のプログラムのようにhourで何時か取得出来るので、時間帯は適当でいいのでif文で分岐すればいいです。やってみて下さい。if文の書き方を知らないとか忘れたとかであればこれも調べてやってみて下さい。
出来たら、次に地域を変更してどうような時間(日本との時差)になるかやってみて下さい。地域の指定方法もぜひ調べてやってみて下さい。
int型の拡張
最後にint型の拡張として、myint型を作ってみます。これは、オブジェクト指向のメリットの部分で書いた「拡張性」を確認します。まず以下のクラス定義を見てください。
これはmyintというクラスの定義ですが、intクラスを継承、つまり引き継いでいるという定義です。但し、拡張は何もしていないのでただintクラスと同じように使えます。
typeで確認すると以下にように表示されました。
ここからint型を拡張すると意味で minusというメソッドを追加してみます。特に実用性はないですが、以下のように出来ました。
自分自身の値(self)に-1をかけて結果を返すというメソッドです。このようにint型に限らずクラスであればこのように拡張して使えるということです。
もし、より詳細が必要であれば以下等を参照して下さい。
(このシリーズ各回の2ページ目からはユーザ登録が必要になりますが、内容は非常にいいと思います。)
[Python入門]クラスの継承 (1/2)
これに何のメリットがあるのかということになりますが、このようにクラスの継承を使わなければ、int型のプログラムの全体をコピーしてそのプログラムをmyintという型にするとします。そうすれば、int型とmyint型で同じ処理の部分が重複します。この部分に変更が必要となれば、両方を修正する必要があります。これでは効率は悪いですし間違えることも多くなります。クラスの継承を使えば、共通の部分はint型のみに存在します。
このように実際のプログラミングでは、オブジェクト指向の期待出来るメリットをどう実現するかだと思います。
最後にまとめ的に
以上、オブジェクト指向言語の考え方(非オブジェクト指向言語との違い)の導入部分について書きました。
とにかく、プログラミングの実務的にはあまりオブジェクト指向(の難しくなりがちな用語)を理解しようとしないで、簡単な考え方から始めて、Python3ですと、ライブラリ関連が充実しているのでそれを使ってみて下さい。
その上で時間がかかりますが、クラスの設計方法や専門分野の知識と実際のプログラミングを合わせていってみて下さい。もちろん、私自身も普通に現役でプログラミングを行っているのでこれからもやっていきます。
また書きます。