超初心者のためのクラス(class)の理解

 クラスを覚えようとすると一度に襲ってくる知識量が多いので、理屈からいこうとすると挫折しがちだ。「とりあえずこう書けばこう動く」みたいなところを体感し、使っていきながら理屈を後付けしていくのが初心者にとっては良いと思う。
 ここでは同じ出力をえるコードについて、関数なし→def関数あり→クラスあり の順で書きながら違いを説明していく。その過程で「こう書けばとりあえず動く」をきっと理解してただけると思う。

以下の例では、コード上で「20歳のTaroさん」を作って、その情報(名前、年齢)を出力していく。


関数を使用しない場合

[コード]

Person1 = ["Taro", 20]

print(f'私の名前は{Person1[0]}で、{Person1[1]}歳だ。')

[出力] 

 変数 Person1 に名前と歳が入ったリストを充てた。そして位置番号で呼び出して出力した。この程度であればこれで十分ですね。

def関数を使用する場合

[コード]

Person1 = [ "Taro", 20 ]

def Property(p_list):
    print(f'私の名前は{p_list[0]}で、{p_list[1]}歳だ。')
    
Property(Person1)

[出力] 

 print()を関数Property内に移動して、関数にリストを渡す形にした。クラスを学ぼうとする人にとっては流せる内容だろう。さて、ここからが本題です。

クラスを使用する場合①

[コード]

class Character:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
Person1 = Character("Taro", 20)

print(f'私の名前は{Person1.name}で、{Person1.age}歳だ。')

[出力] 

 うん、仰々しくなってきましたね。__init__ ?、 self って何? なんて思ったのではないだろうか。よくクラスは設計書で、それを実体化(インスタンス化)して使う~ みたいな説明をされる。今この例えがイマイチわからなくても大丈夫です。一個ずつ追っていきましょう。

まず、設計書を見てみよう。

 ここにはCharecterを使う(作る=実体化)時にどのように処理(設定や実行)するかについてしか書かれていない、だから設計書である。次に処理内容を確認する。
 まず「__init__」については、クラスを使う時にほぼデフォルトで書くコードだと思ってよくて、ここではCharecterを作る時に同時に実行する内容を書くための宣言みたいなものだ。特殊関数と言われるものの一つである。
 その実行する内容はインデントを下げて書かれた、「self.name ~ 」のところであるが、ここでまた「self」も何だ? と最初は思うだろう。この「self」「このCharacterの」位で捉えて置けば良い。つまり「self.name」は「このCharacter の name という変数は」という意味となる。そしてその変数は「name」 という変数に等しいということになる。この「name」はCharecterを作る時に(外から)与えられるものである。

 設計書の説明は以上になるが、実際の動きは↓を見て貰う方が理解が早いと思う。


では実際にTaroさんを作ってみる。

 こうやって書いてみるとリストに似ていますよね。実はリストにも裏で設計書があるから、我々は [ ] でくくるだけで扱えているだけなんですよね。

話を元に戻して、コードを実行したときの動きは以下のようになる。

 Taro,20歳の特徴を持つPerson1というキャラクターを作るために、Character()に「"Taro", 20」 を入れて実行している。同時に設計書の「__init__ 」関数に従って、キャラクターの変数 「self.name」 と 「self.age」 に それぞれ"Taro" と 20 が代入される。なお、代入されるわけではないが、ここでの「self. 」は「Person1の」ということである。だいぶ仰々しいがTaroさんを作れた。これが実体化である。

最後にPerson1ことTaroさんから情報を引き出す。

 Peson1の「self.name」である "Taro"を引き出したいので、「self」にPerson1を入れる感覚で、「Person1.name」と書けば良いだけである。ageも同様に引き出すことが可能である。

 とりあえずクラスを使って書くことができたが、さらに情報を出力するところまでクラス内で実行させることも可能である。

クラスを使用する場合②

[コード]

class Character:
    def __init__(self,name,age):
        self.name = name
        self.age = age
        
    def Property(self):
        print(f'私の名前は{self.name}で、{self.age}歳だ。')

Person1 = Character("Taro", 20)

Person1.Property()

[出力] 


①と同様に設計図から確認してみる。

 見ての通り、クラス内に新たに情報を出力する関数(Property)を加えた。これをメソッドとも言う。もしPerson1がゲームのキャラクターであるならば、自分のステータスをしゃべる機能を追加したような感じだ。
 defの使い方は基本的に変わらないが、クラス内で使用する上では他に変数がなくても、「def 関数(self):」のように「self」が必要となる。また、クラス内で 「self.変数 」を使う場合はそのままselfのままで良い点も認識しておこう。(①は外からのためselfを置き換えた)

キャラクターの作成は①とまったく同じである。

 最後に、情報を引き出すにはどうすれば良いだろうか。この場合、クラス内の関数「 Property(self)」 をクラス外から指示して実行することになる。

 あまり難しくはなく①で変数を引き出した時と同じ感覚で、「Person1.関数()」とすれば良いだけである。

まとめ

 繰り返しになるが、今回の実行内容ではわざわざクラスを書く必要はない。クラスどころか関数もいらないかもしれない。だが、動作部分を非常に簡単して、クラスなし・関数なしのコードと比較することでクラスの実態が少し理解頂けたかと思う。
 クラスの力は、複数人で仕上げていくような大規模なコードでクラスの「継承」を使っていく時に発揮されるもの(らしい)が、私のように表面的に利用しているものにとっては、コードが秩序だってスッキリするとか、なんか素人っぽくないって自己満足するだけのものである。でももし本当に必要になった時にすぐにスタートラインに立つためにこれくらいは知っておいて損はないと思います。
 それから、もしクラスに最初にチャレンジする時は、自分が過去にクラスなしで完成させたコードから取り組むと良いと思います。いきなり新しいものに取り組むと「個別のコードのトラブル」と「クラスを入れることによるトラブル」が入り混じって非常に混乱するからです。