移動式のブログ

ガジェット、アニメ、プログラミング、考えたことその他色々・・・特にこれといったテーマはないカオスなブログです。

クラス(class)とは

クラスについて(Python

「クラス」について適当にメモしておこう。

関数

プログラミングでクラスという、関数みたいなやつが存在する。
関数は大雑把に言ってしまえば、「食材を入れると料理になって出てくる筒」みたいに考えておけば良い。
f:id:idoushiki:20180716102227p:plain

小麦粉1kgと抹茶の粉1kgとチーズ1kgをクラスに入れると、3kgの量の抹茶チーズパンが出てくる。
みたいなイメージだ。

クラスやインスタンスとは何か

まず、クラス
クラスは、「関数の集まり」みたいに考えておけば良いが、関数とは違うところとして、
値を保存しておくことができる。
関数の場合、関数内のローカル変数は関数の処理終了後に消滅するがクラスはそれが保たれる。

そして、インスタンス
さっきのパンで例えると、クラスは自分のオリジナル設定のパン製造機を何個も作ることができる。
インスタンスとは、「クラスによって生成されたオリジナルのパン製造機」と考えれば良い。
関数の場合は、オリジナルのパン製造機を作るためには

def bread(menu,am):
    global amount
    amount=amount+am
    msg=menu+str(amount)
    print(msg)

↑みたいなコードの塊を作るぶんだけいくつも書くことになる。
例えば種類の違うパン製造機を3つ作りたい場合は上記のコードの塊を3回分書くとかしないといけないので大変だ。
そのため、作りたいパン製造機の台数が増えれば増えるほどコードの量がとても多くなる。

class Bread:
    def __init__(self,menu="cheese "):
        self.menu=menu
        self.amount=0

    def br(self,g):
        self.amount+=g
        msg=self.menu+str(self.amount)
        print(msg)

しかし、クラスの場合は一度上記のようなコードを書けば、
あとは"bread2=Bread()"こんな感じの短いコードを書くだけで、
設定の違うパン製造機をいくらでも新しく作ることができる。
そして、"bread2=Bread()"の「bread2」がインスタンンスである。
つまり、様々な機能をたくさん作りたい場合は、
クラスを利用した方がコードが短いかつ、見やすくかけるということだ。

さっきのパンで例えると「抹茶パン専用の製造機」や「チーズ味のパン専用の製造機」がインスタンスである。
f:id:idoushiki:20180716102447p:plain



クラス 実際に書いたコードの動作(python)

「cheese味とgreentea味のパンをいくつ生産したかを表示する」みたいな感じのコードを書いてみた。

このコードで解説してみよう。

bread1=Bread("greentea ")
bread2=Bread()

このコードは、インスタンスを作成しているコードだ。

これでbread1とbread2というインスタンスを作成したことになる。
つまり、bread1というgreentea味のパン製造機、
bread2というパン製造機を作ったということになる。

Bread()内に、greenteaを入れたものと、何も入れていないものがある。
かっこ内が空の場合、class内にある「def __init__(self,menu="cheese "):」
の引数で値を設定している場合はその内容となる。
デフォルトの値を設定しなくても良いならそのまま"menu"と書けば良い。

このコードでは、
menu="cheese "と書かれているため、
かっこが空のやつは「cheese」の文字が設定される。
つまり、チーズ味のパン製造機ということだ。

コンストラクタ、def __init__()とは

この部分は初期化メソッドと言って、インスタンスを作成した時だけ最初に実行される部分だ。
コンストラクタとも言う。
つまり、インスタンスのbread2の場合は、
「bread2=Bread()」のように、インスタンスを作成するコードが実行された時だけ「__init__」の部分が実行される。
それ以降はbread2を実行しても「__init__」の部分は実行されないということだ。

self.menu=menu
self.amount=0

コンストラクタで上記のようなコードが実行される。
まず、bread1によって作成したインスタンスなら、
self.menuにgreeateaが設定されるので、
bread1はgreentea、そして、self.amountに0が設定される。

この二行のコードによって「menu=greentea amount=0」のデータをbread1が持つことになる。
そして、bread1.br(20)というコード、
つまりbread1のインスタンスのbr()に20の値を与える。

そうすると、brの引数のgに20が代入される。
そしてさっきコンストラクタで設定したように値が0のamountに20が加算されるので、
amountは20になる。

msg=self.menu+str(self.amount)
print(msg)

この部分でmenu「greentea」とamount「20」をつなぎ合わせて ”greeatea 20”というように画面に出力される。

もしこれが関数だった場合、
この時点で関数から抜け出したら関数内のローカル変数のamountの値が失われてしまう。
しかし、クラスの場合はこの「20」という値と
「greentea」という文字が(この例だとbread1に)保持されるので、
次に「bread1.br(20)」を実行すると"greentea 40"と出力される。

つまり、パンで例えれば、「20個の抹茶パンを製造する」という操作を2回行ったので
合計で抹茶パンが40個製造されたと例えられる。


self

selfは、変数に入れた値を保持することができる。
そして、クラス内のすべてのメソッドで変数内の値を共有することができる。

今回の例の場合、selfをつけた変数はbread1やbread2に設定される。
selfをつけないと、その変数に入っている値は保持されないので、
今回の「self.amount」みたいな値を保持すべき変数にはselfをつける。
そして、selfをつけた変数の値はクラス内全てのメソッド(def br():みたいな関数的なやつ)で共有される。
f:id:idoushiki:20180716192037p:plain



コードの実行結果 

bread1.br(20)
bread2.br(15)
bread1.br(20)
bread2.br(15)
bread1.br(20)

今回の例のコードでは上記のように書かれているので、実行結果は以下の画像のようになる
f:id:idoushiki:20180716091333p:plain
見ての通り、greeateaはgreentea自身の値を保持しているし、cheeseもcheese自身の値を保持している。
グローバル変数などを定義しているわけではない。
インスタンスに値をぶち込んだら、今までにぶち込んだ値の合計が文字とともに出てくるのだ。
さらに、そして、bread1もbread2もそれぞれの持つ値は独立しているので、
数値が混ざることなく、加算されているので、新たに専用の変数を定義する必要がない。
これは便利だ。




実践力を身につける Pythonの教科書

新品価格
¥2,786から
(2018/7/16 12:15時点)