Raspberry Pi & Python 開発ブログ ☆彡

Raspberry PiとPythonの基本的な使い方をわかりやすく解説。初心者、入門者必見!!

クラスの基本的な使い方

ブログ管理者のP.Hです!

今回はクラスの基本的な書き方、使い方について説明しようと思います。 オブジェクト指向には主に3つの機能がありますが、それらを詳しく説明するために まずは基本的なクラスの書き方、使い方を先に勉強しておきましょう。

クラスとは

クラスとは変数や関数をひとつのまとまりとしてコーディングする記述法です。 機能ごとにクラスとしてコーディングすることにより、とても管理しやすくなります。

もっともシンプルなクラス

下記がクラスの書き方の例になります。書き方は覚えるしかありません。

# --- ここからクラス---

class MyClass: # class クラス名(クラス名は任意 わかりやすい名前にする)

    def __init__(self):# コンストラクタ はじめに1回だけ実行される。変数の初期化に主に使われる 
        self.name = "" # nameという変数に初期値""を設定する

    def set(self, name): # 引数の値をnameという変数にセットする関数 
        self.name = name

    def get(self): # name変数の値を表示する関数
        print(self.name)

    def set_get(self, name): # 上記のsetとget関数を実行する関数
        self.set(name)
        self.get()

# --- クラス終わり---

a = MyClass() # クラスをインスタンス化(メモリに展開する)
a.set("123") # "123"という値をセットする
a.get() # "123"という値が表示される
a.set_get("abc") # "abc"という値をセットし、"abc"という値が表示される

いくつか疑問点があると思いますので、解説してきます。

selfとは何か?

pythonのクラスではじめに悩むのは、selfという記述ではないかと思います。翻訳すると自分という訳になると思います。 内部的にプログラムがどのように管理されているかを知る良い機会だと思いますので、少し複雑ですが、説明します。

selfとはクラスのメモリの先頭アドレスになります。上記の例題でいえば、MyClassクラスのメモリの先頭アドレスです。 ここで重要になってくるのが、下記の記事です。

www.raspberrypirulo.net

下記のようなイメージになります。イメージですので、メモリ番地等は適当です。

メモリ構造のイメージ

実際のコーディングでメモリ番地を知る必要はありません。python言語が管理してくれます。

self.nameは 0x00001000(self) + 0番地シフト(name)でメモリアドレスがわかります。 クラスの先頭アドレスのselfを基準にするため、selfが必要になるのです。 プログラムをする上で、クラスの先頭アドレスは非常に重要だと言うことを覚えておいてください。

インスタンス化とは?

クラスのコードは、ここからクラス~クラス終わりまでですが、これだけだと ただテキストファイルに文字を書いただけでプログラムは何も実行されません。

自分でクラスのプログラムをメモリに展開する必要があります。これをインスタンス化と言います。 上記例題で言えば、下記の一行でインスタンス化しています。これを書いて初めてクラスのプログラムが実行可能になります。

a = MyClass()

aにはMyClassのメモリの先頭アドレスが格納されます。selfにもこのアドレスが格納されます。 アドレスが何番地になるかはpython言語が自動的に割り当てるため、プログラマは考える必要ありません。

上記例題でいえば、
a.set は 先頭アドレス:0x00001000(a) + 4番地シフトしたアドレスにある関数
a.get は 先頭アドレス:0x00001000(a) + 6番地シフトしたアドレスにある関数
a.set_get は 先頭アドレス:0x00001000(a) + 8番地シフトしたアドレスにある関数

としてpython言語は認識し、実行することができるのです。

これは同じものか別のものか

下記の2つのコードについて考えてみてください。解説はコードのコメントを参考にしてください。

a = MyClass()
b = a # bにはaのアドレスが格納される。aとbは同じもの

a = MyClass()
b = MyClass() # aとbは別のもの。MyClassクラスが2つ、メモリ上に展開される。下記の図のイメージ

MyClass aとbの2つがメモリ上に展開される

まとめ

メモリアドレスが出てきて難しかったかもしれませんが、クラスの先頭アドレスを基準に クラス内の変数や関数は何番地シフトしているか、という情報で管理されています。 そのため、基準となるクラスの先頭アドレス(self)がとても重要になります。

また、クラスは明示的にメモリに展開する必要があり、これをインスタンス化と言います。 インスタンス化しないと何もプログラムは実行されません。

基本的なクラスに使い方について解説しました。次回から、オブジェクト指向の3つの機能について 具体的に解説していきます。