どうもこんにちは。コンです。
Pythonのコードを書き始めて5年。
5年もコードを書いていれば、なんでもPythonのことは分かると思っていたのですが。。。
実際は全然そんなことはないです(笑)
並行処理のプログラムの書き方も昨年に入ってから覚えましたし、
知らないライブラリだって山のようにあります。
今日は理解に時間がかかったプログラミングのClassについて書いていこうと思います。
いつもdef関数で書いてしまうのですが
私も勉強がてら、ここで基本を勉強していきたいと思います。
どんな言葉がでてくるのか
Pythonを始めたばかりだと色々な言葉が出てきて、大変かと思います。
そこで今回のPythonで取り扱うオブジェクト指向で覚えていく言葉としては以下の用語です。
★とりあえずこの語句から覚えて欲しい
・メソッド:クラス内で使用する関数。
・インスタンス:クラスから生成して実体化したもの。
・コンストラクタ:最初に行うことを定義するメソッド。
まずはこれらの言葉を使ってPythonのコードを書いてみましょう。
Pythonにおけるクラスの書き方
今回は「四角形の面積と辺の長さの合計(周囲)」をPythonのクラスを使って計算してみましょう。
ここではクラスに以下の2つの変数を渡します。
・width(縦)
・length(横)
内容自体はdef関数でも簡単に書くことが出来ますが、クラスで作っておけば面積と周囲を共通の変数で計算することができ、
後で別の計算(例えば対角線の長さ)をしたい時、クラス内の関数を追加することで共通の変数を使うことが可能になります。
以下にクラスで書いたコードを記載します。
ここからClassで使う順番に解説をさせてもらいます。
クラスの命名規則
クラス名は大文字始まりとして、複数の単語を使う場合は2番目以降の単語も大文字始まで書くそうです。
ちなみに、def関数の場合はrectangle_calc():みたいに、複数の単語を使う場合は、単語の区切りにアンダースコア(_)を組み合わせて名前を付けるのが一般的らしいです。(知らなかった…)
今回はRectangleCalc()とこの命名規則を適用させてもらいました。
書き方としては
class クラス名:
コンストラクタやメソッドを記述
といった感じになります。
コンストラクタ
クラスの名前がきまったら、最初に実行する内容を定義します。
この時に記述するメソッドのことをコンストラクタといいます。
Pythonのクラスでコンストラクタを定義するメソッドもdefを使って書きます。
initをアンダーバー2個ずつで挟み、def関数で書くコンストラクタは「__init__():」メソッドを使うことがルールです。この_init_():メソッドにより、インスタンスを作成する際、変数に値を代入するなどの初期処理を行うことが可能になります。
上のクラス名とコンストラクタを記述したものが以下になります。
class RectangleCalc:
# コンストラクタ(初期化メソッド)
def __init__(self, width, length):
#入力する変数width・lengthを設定
self.width = width
self.length = length
#計算するarea・perimeterをを初期化
self.area = 0
self.perimeter = 0
ここで私が最初、Pythonのクラスの書き方でわからなかったのが
ってなってました。
この疑問を解決するに、私はまずドット「.」に注目していきました。
外部ライブラリを使うときもドット「.」を使いますよね。
この例えばnumpyを使うときはnumpy.loadtxt()のように使います。
今回の「self」は上の段落でいうとnumpyの部分にあたります。
つまり文字通り自身のことを示しているのですが、作成されるインスタンス自身を指します。
前後が逆になってしまうのですが
ベタ書きで実行しているコードでいう部分のselfはRectangle1とRectangle2を示しています。
#インスタンスを生成
Rectangle1 = RectangleCalc(width=3, length=4)
Rectangle2 = RectangleCalc(width=10, length=10)
# メソッドを実行
Rectangle1.calc_area()
Rectangle1.calc_perimeter()
Rectangle2.calc_area()
Rectangle2.calc_perimeter()
当たり前のポイントかもしれませんが、基本的にはクラスのメソッドを書く時のみ使います。
メソッドを追加
コンストラクタを書いた後は、メソッドを追加していきます。
ここはdef関数の書き方と同じなので、もし不安がある方は関数の書き方をご参考ください。
書き方のポイントとしては、コンストラクタ部の変数を使う時に、「self.」を頭に付ける所です。
メソッドで新しく変数を設定するにはselfは要りません。
メソッドを生成・実行
クラスを使って、三角形の結果の値を取り出してみます。
最初は、作ったクラスを実際に使うためにインスタンスを生成します。
インスタンスの生成は、「インスタンス名=クラス名(変数)」と書いて生成します。
#インスタンスを生成
Rectangle1 = RectangleCalc(width=3, length=4)
Rectangle2 = RectangleCalc(width=10, length=10)
メソッドの実行は生成したインスタンス名とメソッド名をドットで繋ぎ「インスタンス名.メソッド名(変数)」と書きます。
計算された変数を取り出すためには、「インスタンス名.変数名」と書きます。
# メソッドを実行
Rectangle1.calc_area()
Rectangle1.calc_perimeter()
Rectangle2.calc_area()
Rectangle2.calc_perimeter()
# クラスから変数を取り出して表示
print("Rectangle1の面積", Rectangle1.area)
print("Rectangle1の周囲", Rectangle1.perimeter)
print("Rectangle2の面積", Rectangle2.area)
print("Rectangle2の周囲", Rectangle2.perimeter)
このように共通のメソッドや変数をまとめ、使いまわしが出来るようプログラミングがオブジェクト指向の利点で、再利用性が高いと言われているポイントだそうです。
応用例:継承
上の例でクラスの基本が分かってきたら、次は継承を理解していきます。
本当は継承も基本かもしれませんが、Pythonが初めてのプログラミング場合は応用も応用です。
(あれ??私が難しいと感じているだけかな??)
Pythonのクラスは、既存のクラスの内容を引き継ぎ、さらに新しいクラスを定義することができます。
元の既存のクラスをスーパークラス、新しいクラスをサブクラスを呼びます。
Class サブクラス名(スーパークラス名):
コンストラクタと追加のメソッド
のように書きます。
次は先ほどの四角形の面積・周囲を計算するクラスを利用して、直方体を体積を計算するサブクラスを書いてみましょう。
早速ですが書いたコードはこちらになります。
結構長くなってしまったので、ポイントを解説していきますね。
組み込み関数super()
サブクラスのコンストラクタで、super関数を使って
「super().__init__(継承したい変数)」と定義しています。
今回はコンストラクタで変数を継承しましたが
実際はサブクラスのメソッドで、スーパークラスのメソッドを継承も可能です。
このあたりはさらに応用のオーバーライドについてで書いていきます!!
おわりに
ここまで長い記事を読んでいただき、本当にありがとうございます!!
今回はPythonのクラスの使い方を説明させてもらいました。
基本的なクラスの書き方は
- 計算する内容と仕様(どんな関数や変数を使うのか)を決める
- コンストラクタで変数の初期化を定義
- メソッドを定義
の順で定義していき、以下の順で実行していきます。
- インスタンスを生成する
- メソッドを実行する
私もこの記事を書いていて、まだまだ勉強が足りないなと感じましたので、
また勉強していきたいと思いました。
重ね重ねにはなりますが
ここまで読んでいただき、誠にありがとうございました。