1. TOP
  2. ブログ
  3. 具体例で学ぶ、Pythonのclassの使い方

具体例で学ぶ、Pythonのclassの使い方

Pythonではclassを活用してプログラミングができます。
しかしclassの概念は初学者には理解が難しく、
・何のためのものかイメージしづらい
・どういうときに使いたいものなのかイメージしづらい
と感じている方も多いのではないでしょうか。

そこで本記事では、
・クラスとはどういうものか
・どういうときに使うものなのか
について説明し、具体的な使い方をコードを交えて解説します。
少しでもイメージしやすいように、具体的な使用イメージがわくようなコード例、丁寧なコメントによる、初学者でも理解しながら実行できるコード例を心がけています。
ぜひ手元で実行しながら、できれば少しずつでもコードを改造しながらお読みいただけますと幸いです。

Pythonについてはこちらもどうぞ

ますます重要度をPython〜その実情と将来性に迫る

 

classとは

 

classを使用すると、関数を定義するときのように複数の処理や値をまとめておくことができます。
classからは「インスタンス」というものが作成でき、インスタンスにはデータを保持させておくことができたり(属性)、関数のように処理をまとめておくことができたり(メソッド)します。
このように、「1つのもの(オブジェクト)に情報や処理をひも付けて管理できる」のがclassです。

例えば、「人間」というclassがあるとしましょう。
人間classをひな形として1人1人の個人が作られます。
この人間インスタンスにはそれぞれ共通する
・属性:名前や年齢、性別、お腹の空き具合
・メソッド:食べる、寝る
などの項目が設定されている、というイメージです。

classを作成しておくことで、似たようなインスタンスを自由に生み出すことができます。
そのため、classはインスタンスを作成するための「ひな形」「設計図」「工場」などとも言われます。

classの「継承」という機能を使うことで、とあるclassから派生したclassを作ることも簡単にできます。
例えば、「人間」classを拡張した「大人」classでは、「人間」classで設定した属性、メソッドに加えて
・属性:年収、仕事、趣味、好きなもの
・メソッド:歩く、走る、話す、働く
などを追加することができます。

このように、classを活用すれば
・似たようなコードを繰り返し書く必要がなくなる
・コードを再利用しやすい
・機能を拡張しやすい
という恩恵が得られます。

 

 

classはどんなときに必要なのか

 

classはPythonを始めたばかりのころはあまりお世話にならないかもしれません。
そのため
「classを使わなくてもプログラミングできてる。classって何に使うんだろう…。」
と疑問に思うことでしょう。

classは「対象となる物」を作成し、対象物に関する情報や動きをひとまとめにして使い回すことができます。
classが必要になる場面としてイメージしやすいのはゲーム制作です。
ゲームでは登場人物や敵キャラ、使用する道具などさまざまなものが登場します。
これら全て、固有の情報や動き方、使い方が備わっているため、それぞれの共通部分をclassにすることでコーディングが効率的になります。

このように、多様なものをたくさん用意する必要がある場合にclassが威力を発揮します。
そのため、ゲーム以外にも、何かしらの対象物を作成して扱う必要があればclassを活用できるでしょう。

また、Pythonでいつもお世話になっているrandomやpandasなどといったモジュールでもクラスが活用されています。大規模な開発では、classを使用できるに越したことはないのです。

 

 

Pythonにおけるclassの具体的な使い方

 

それでは、具体例を元にPythonでのclassの使い方を見ていきましょう。
今回はゲームの登場キャラクターのひな形になるclassを作成してみます。
キャラクター共通の機能を持ったCharacterクラス、Characterクラスに追加機能を付けた「村人」(Villager)、「自キャラ」(Hiro)のclassを作成してみます。

 

classの作り方

 

まずはCharacterクラスを作成します。
属性やメソッドを設定していないclassは以下のようになります。
なお、class名は大文字で開始し、単語を繋げるときはCharacterClassのように各単語の頭文字を大文字にします。

class Character: # classを定義する
    pass # デモのため、何もしない

これでCharacterクラスの定義ができました。
実際にCharacterインスタンスを作成するには

chara1 = Character() # chara1変数にCharacterインスタンスを作成

とclassを変数に代入すればOKです。

 

classの属性

 

キャラクターには「名前」(name)、「年齢」(age)、「性別」(sex)という属性を付けることにします。
属性は以下のように設定できます。

chara1.name = 'Kazuma' # chara1インスタンスのname属性の値を’Kazuma’に設定
chara1.age = 16 # chara1インスタンスのage属性の値を16に設定
chara1.sex = 'male' # chara1インスタンスのsex属性の値を’male’に設定

chara1.nameという変数に値を代入したようなものなので、以下のように値を使用することもできます。

print(chara1.name)

出力

Kazuma

別のインスタンスには別の値を設定できます。

chara2 = Character() # chara2変数にCharacterインスタンスを作成
chara2.name = 'Megumi' # chara1とは別の値を設定できる
chara2.age = 13
chara2.sex = 'female'
 
print(chara2.name)

出力

Megumi

ここまでではclassのありがたみはまだ感じられませんが、これから少しずつclassの利点が見えてきます。

 

classのメソッド

 

classにはメソッドを定義することもできます。
関数と同じくdef文を使用しますが、第1引数に「self」というオブジェクトを指定しておく点が特徴的です。

selfはその名の通り「メソッドを呼び出したインスタンス自身」を指します。
インスタンスを表す変数名はさまざまですが、それらを共通してselfとして表現しています。
「メソッドの引数に自分自身を入れることで、自分自身に設定されている属性の値を利用できる」というイメージです。

実際の使い方を見た方が早いですので、以下で「名前」(name)、「年齢」(age)、「性別」(sex)という属性を設定するメソッド(set_data(self, name, age, sex))、これらの情報をprintするメソッド(print_data(self))を設定してみましょう。

class Character:
    def set_data(self, set_name, set_age, set_sex): # 属性に値を一括で設定するメソッドを定義
        self.name = set_name # selfには実際にはインスタンスが入る。
        self.age = set_age # 属性の説明時に各属性に値を設定したのと同じこと。
        self.sex = set_sex
 
    def print_data(self):
        print("私は{}。{}歳。{}です。".format(self.name, self.age, self.sex)) # 各属性の値をprint。

これらのメソッドを使用すれば、属性の説明の例で見たような手間をかけず、一括で必要な属性に値を設定できます。
なお、メソッドを実行する際にはselfを引数に指定せず、第2引数から指定します。

chara3 = Character() # 新しいインスタンスを作成
chara3.set_data('Kazuma', 16, 'male') # 一括で属性に値を設定

def set_data(self, set_name, set_age, set_sex): 内でselfにメソッドを呼び出したインスタンス自身(chara3)が代入されて self = chara3 となっています。
後の引数は関数と同様にそれぞれの変数に代入され、

       
        self.name = set_name
        self.age = set_age
        self.sex = set_sex

       
        chara3.name = 'Kazuma'
        chara3.age = 16
        chara3.sex = 'male'

となっているわけです。

もう1つのメソッドを実行すると

chara3.print_data()

出力

私はKazuma。16歳。maleです。

となり、しっかりと属性が設定され、呼び出しもできることが確認できます。

なお、属性から直接値を呼び出すこともできます。

print(chara3.name)

出力

Kazuma

 

classのインスタンスを作成する際に呼び出されるメソッド

 

各インスタンスそれぞれに属性を設定する機会は多く、いちいち設定するのも面倒です。
そんな面倒さを解消できるように、classにはインスタンス作成時に自動で呼び出されるメソッド(__init__())を定義することができます。
このメソッドは「コンストラクタ」と呼ばれます。

使い方は以下の通りです。
以下コードはメソッドの説明で定義したset_dataメソッドを__init__に変更しただけのものです。

class Character:
    def __init__(self, name, age, sex): # コンストラクタでインスタンスを初期化
        self.name = name
        self.age = age
        self.sex = sex
 
    def print_data(self):
        print("私は{}。{}歳。{}です。".format(self.name, self.age, self.sex))

__init__()の引数は以下のようにインスタンス作成時に指定します。

chara4 = Character('Kazuma', 16, 'male') # インスタンス作成時にコンストラクタが呼び出される
 
chara4.print_data()

出力

私はKazuma。16歳。maleです。

 

継承

 

classの便利な点はコードの使い回しがしやすい点、機能拡張がしやすい点です。
「継承」という機能を利用することで、他で作成したclassのメソッドや値を受け継ぎつつ、メソッド等を編集、追加できます。
定義するclass名の後ろに継承したいclass名を()内に指定すればOKです。

まずは村人(Villager)classを作成してみましょう。
村人にはCharacterクラスの機能に加え、台詞(line)を属性として持ち、台詞を話すspeak()メソッドも定義します。

class Villager(Character): # Characterクラスを継承
    def __init__(self, name, age, sex, line): # コンストラクタを拡張
        super().__init__(name, age, sex) # super()で継承元のクラスを呼び出せる
        self.line = line # 台詞を設定
 
    def speak(self): # 台詞を話すメソッドを定義
        print("{}「{}」".format(self.name, self.line))

Villagerクラスでは、Characterクラスのコンストラクタに台詞の設定も追加しています。
このように、super()で継承元のクラスを呼び出せます。

インスタンスを作成してみると

villager1 = Villager("apple seller", 35, "male", "おう!リンゴでもどうだい?") # インスタンス作成時、属性に値を設定
 
villager1.speak() # 台詞を話すメソッド

出力

apple seller「おう!リンゴでもどうだい?」

また、Characterクラスを継承しているので、Villagersクラスで定義していないprint_data()メソッドも呼び出せます。

villager1.print_data()

出力

私はapple seller。35歳。maleです。

これで村人を大量生産できますね。

同様に、自キャラ(Hiro)classも作成してみましょう。
自キャラにはCharacterクラスの機能に加え、体力(hp)と経験値(ex)、魔力(mp)を属性として持たせます。
また、魔力に応じて体力を回復するheal()メソッドも定義します。

class Hiro(Character): # Characterクラスを継承
    def __init__(self, name, age, sex, hp, ex, mp): # コンストラクタを拡張
        super().__init__(name, age, sex) # super()で継承元のクラスを呼び出せる
        self.hp = hp # 体力を設定
        self.ex = ex # 経験値を設定
        self.mp = mp # 魔力を設定
 
    def heal(self): # 魔力に応じて体力を回復するメソッド
        self.hp += self.mp # 体力を魔力分回復
        print("HPが{}回復".format(self.mp)) # 回復量を表示
        print("現在のHP:{}".format(self.hp)) # 回復後の体力を表示

インスタンスを作成してみると

hiro1 = Hiro('Kazuma', 16, 'male', 100, 200, 30)
 
hiro1.heal() # 魔力分の体力を回復するメソッド

出力

HPが30回復
現在のHP:130
 
hiro1.print_data() # Hiroクラスで設定していないメソッドも、継承元から呼び出せる

出力

私はKazuma。16歳。maleです。

このように、共通する機能を持つclassを作成し、classを継承した新しいclassを作成することで機能を追加することができます。

 

 

classを使いこなして一段上のPython使いに

 

クラスの使い方を具体例とともに解説しました。
ここで解説した使い方はごく基本的なものですが、一歩を踏み出しておけば応用も理解しやすいでしょう。
小規模なソースコードでは活用するタイミングは無いかもしれませんが、classを使いこなせればできることが増えそうだと感じていただけたのではないでしょうか。

classは「習うより慣れろ」だと言われます。使えそうな場面を見つけ、classの使い方を調べながら積極的に活用してみましょう。

 

▽関連記事はこちら

Python、クラスや関数へのコメントの書き方

PythonでGUIアプリをつくる!おすすめのライブラリとは

 

▼キャパの公式Twitter・FacebookではITに関する情報を毎日更新しています!

 

建設・土木業界向け 5分でわかるCAD・BIM・CIMの ホワイトペーパー配布中!

CAD・BIM・CIMの
❶データ活用方法
❷主要ソフトウェア
❸カスタマイズ
❹プログラミング
についてまとめたホワイトペーパーを配布中

デジタルツインと i-Constructionについての ホワイトペーパー配布中!

❶デジタルツインの定義
❷デジタルツインが建設業界にもたらすもの
❸i-Constructionの概要
❹i-Constructionのトップランナー施策

CONTACT

株式会社キャパでは、GeneXusの開発・改善について ご相談を承っています。

営業時間:月~金 9:30~18:00 
定休日:土日・祝

 

    カテゴリ一覧

    PAGE TOP