Pythonプログラミングで

クラスのメモ

目次

用語一覧

クラス

複数の文をひとまとめにしたもの。class ClassName: ... で定義する。ここでわからなくてもアウトラインをご覧くださってご理解いただければいいと思います。

インスタンス

クラスのオブジェクト。instance = class とする。ここでわからなくてもアウトラインをご覧くださってご理解いただければいいと思います。

メソッド

クラスの中の関数にあたるもの。クラス内では def method(self, ...) で定義し、class.method() の形で呼び出す。

コンストラクタ

インスタンスを宣言したときに実行されるメソッド。つまりインスタンスの初期化メソッド。コンストラクタの解説部分をご覧ください。

継承

とあるクラスの付加的な機能として新たにクラスを設けること。継承の解説部分をご覧ください。

アウトライン

「クラスとは何か」を考えると少し難しいので、実際に使って見るのがいいでしょう。

まずはこちらを写して実行してみてください。一文一文自分の手で模写してくださいね。何やってるかわからないままコード走らせたって意味ないでしょ。

class MyClass:
    counter = 0
    sum = 0
                            
def add(self, addition):
    self.counter += 1
    self.sum += addition
                        
Instance1 = MyClass()
Instance2 = MyClass()
        
Instance1.add(1)
Instance1.add(5)
        
Instance2.add(2)
Instance2.add(-5)
Instance2.add(1)
        
print('({}, {}), ({}, {})'.format(Instance1.counter, Instance1.sum, Instance2.counter, Instance2.sum))    
                        

するとこうなりますね。

(2, 6), (3, -2)

これでクラスとインスタンスの関係はつかめたでしょう。

まずはクラスの設定です。countersum という二つの変数を用意してあげて、add メソッドを 2 回使います。これで Instance1.counter は 2 に、Instance1.sum は 6 になりました。

クラスの設定が終わったら Instance1Instance2MyClass を代入する形でインスタンスを宣言します。

この仕組みがまだわからない方は専門のサイトに行って勉強してください。一応ここは備忘録ですので。

つまりクラスは鋳型、インスタンスは鋳型から出てきた道具です。鋳型はそれ自体だと有用な道具としては使えませんが、インスタンスを宣言する、つまり鋳型に金属を流し込む作業をすることで、ちゃんと使える道具が出来上がります。

コンストラクタ

クラスのコンストラクタはインストラクタの初期化メソッドとでも言えばいいでしょうか。とりあえず次のコードを写して実行してみてください。

class MyClass:
    def __init__(self, input_sum=0):
        self.counter = 0
        self.sum = input_sum
    
    def add(self, addition):
        self.counter += 1
        self.sum += addition
    
Instance1 = MyClass(5)
Instance2 = MyClass()

Instance1.add(1)
Instance1.add(5)

Instance2.add(2)
Instance2.add(-5)
Instance2.add(1)
print('({}, {}), ({}, {})'.format(Instance1.counter, Instance1.sum, Instance2.counter, Instance2.sum))
    
                    

出力はこうなるはずです。

(2, 11), (3, -2)

アウトラインをご覧になった方なら「これさっきのコードとだいぶ似てるな」と思ったでしょう。まさしく、先ほどのコードをほぼコピペした物です。が、ご承知の通りクラスの冒頭に __init__ というメソッドができていますね。また Instance1 を定義するときに、引数として 5 が入れられています。どういうことでしょう?

このクラスの最初にあるメソッド __init__ をコンストラクタといいます。インスタンスを宣言したときに実行されるメソッドです。つまり、Instance1 を引数 5 で呼び出したとき、__init__(self, 5) を実行したことになるのです。同様に Instance2() を呼び出したときは __init__(self, 0) を実行しています。

したがって Instance1 を呼び出したとき、Instance1.counter == 0, Instance1.sum == 5, Instance2.counter == 0, Instance2.sum == 0 となっています。

クラスでいうところの第 2 引数 input_sum は、デフォルトで 0 と設定しています。この書き方をすることで、もしインスタンスを宣言するときに引数を入れてくれたら input_sum はその入力値にします。入力がなかったら input_sum は 0 です。

継承

とりあえず一つクラスを普通に宣言したとします。

                    
class MyClass:
    def __init__(self):
        self.base = 1
        self.addition = 1
        self.count = 5
        
    def add(self):
        x = self.base
        for i in range(self.count):
            x += self.addition
        return x
                    
                

この MyClass クラスに加えてもう一つクラスを作りたいのですが、できることなら MyClass のメソッドをそのまま使いたい。こんな時に「クラスの継承」という技を使います。

                    
class MyClass:
    def __init__(self):
        self.base = 1
        self.addition = 1
        self.count = 5
        
    def add(self):
        x = self.base
        for i in range(self.count):
            x += self.addition
        return x


class SubClass(MyClass):
    def sub(self):
        x = self.base
        for i in range(self.count):
            x -= self.addition
        return x


instance = SubClass()
print(instance.sub())
print(instance.add())
                    
                

新しく SubClass でやった中でこれまでと違うのは、クラスを定義する時に

class 新クラス名(継承するクラス名)

ってしたことだけですよね。ですがよくご覧ください。SubClass の中では base や count といった変数を定義していないのに、何食わぬ顔で使っている。実際これを動かしてみましょうか。

                    
-4
6
                    
                

何も問題なく動きましたよね。ではコードの末尾にこう付け加えたらどうなるか。

                    
instance2 = MyClass()
print(instance2.sub())
                    
                

当然エラーがでますね。

'MyClass' object has no attribute 'sub'

self について