Contents
はじめに
Pythonの学習を進めていくと、避けては通れないのが「クラス」です。
クラスは、初心者にとって少し難しく感じやすいポイントです。
class__init__selfこのような見慣れない記述が一度に登場するため、急に難しくなったように感じるかもしれません。
しかし、クラスの基本的な考え方はそれほど複雑ではありません。
クラスとは、簡単にいえば、データと処理をひとまとめにするための仕組みです。
この記事では、クラスの基本から、インスタンス、__init__、selfの役割まで、初心者向けに順番に解説します。
クラスとは
クラスとは、データや処理をまとめるための設計図のようなものです。
例えば、ゲームに登場するキャラクターをPythonで管理するとします。
キャラクターには、次のような情報があります。
- 名前
- HP
- 攻撃力
また、キャラクターが行う処理として、次のようなものがあります。
- 自己紹介する
- 攻撃する
- ダメージを受ける
これらのデータと処理を、ひとまとめにして管理できるのがクラスです。
クラスを使わずにキャラクターの情報を管理する場合、次のように複数の変数を用意することになります。
character_name = "スライム"
character_hp = 100
character_attack = 20キャラクターが1体だけであれば、この書き方でも問題ありません。
しかし、キャラクターが増えると変数の数も増えていきます。
character1_name = "スライム"
character1_hp = 100
character1_attack = 20
character2_name = "ドラゴン"
character2_hp = 500
character2_attack = 80キャラクターが10体、100体と増えていくと、管理が難しくなります。
このような場合に、クラスを使うと関連する情報をまとめて管理できます。
クラスの基本的な書き方
Pythonでは、classを使ってクラスを定義します。
基本的な書き方は次のとおりです。
class クラス名:
処理実際に簡単なクラスを作ってみましょう。
class Character:
passCharacterという名前のクラスを定義しています。
クラス名は自由に決められますが、Pythonではクラス名の先頭を大文字にするのが一般的です。
例えば、次のように単語の先頭を大文字にして書きます。
class Character:
passclass PlayerCharacter:
passこのような書き方を、パスカルケースと呼びます。
また、passは「何もしない」という意味です。
Pythonでは、クラスの中を空のままにできません。
そのため、クラスの内容をあとから書く場合などに、仮の処理としてpassを記述します。
インスタンスとは
クラスを定義しただけでは、まだ実際に使えるデータは作られていません。
クラスという設計図をもとに、実際のデータを作る必要があります。
クラスから作られた実際のデータを、インスタンスと呼びます。
class Character:
pass
character = Character()このコードでは、Characterクラスからインスタンスを作成しています。
Character()クラス名の後ろに丸括弧を書くことで、インスタンスを作成できます。
作成したインスタンスは、変数に代入して使用します。
character = Character()ここでは、作成したインスタンスをcharacterという変数に代入しています。
クラスとインスタンスの関係は、次のように考えると分かりやすいです。
- クラス:設計図
- インスタンス:設計図から作った実物
例えば、たい焼きの型がクラスで、その型を使って作ったたい焼きがインスタンスです。
同じ型から、複数のたい焼きを作ることができます。
同じように、1つのクラスから複数のインスタンスを作成できます。
class Character:
pass
character1 = Character()
character2 = Character()
character3 = Character()character1、character2、character3は、すべてCharacterクラスから作られた別々のインスタンスです。
属性を持たせる
インスタンスには、名前やHPなどのデータを持たせることができます。
インスタンスが持つデータを、属性と呼びます。
属性は、次のように設定できます。
class Character:
pass
character = Character()
character.name = "スライム"
character.hp = 100
print(character.name)
print(character.hp)実行結果は次のとおりです。
スライム
100
属性にアクセスするときは、インスタンス名と属性名をドットでつなぎます。
インスタンス名.属性名値を設定する場合は、次のように書きます。
character.name = "スライム"値を取得する場合も、同じようにドットを使います。
print(character.name)ただし、インスタンスを作成したあとに毎回属性を設定するのは少し面倒です。
character1 = Character()
character1.name = "スライム"
character1.hp = 100
character2 = Character()
character2.name = "ドラゴン"
character2.hp = 500このような処理を簡単にするために使われるのが、__init__です。
__init__とは
__init__は、インスタンスが作成されたときに自動的に実行される特別なメソッドです。
基本的な書き方は次のとおりです。
class クラス名:
def __init__(self):
処理実際に書いてみましょう。
class Character:
def __init__(self):
print("キャラクターを作成しました")
character = Character()実行結果は次のとおりです。
キャラクターを作成しました
コード上では、__init__を直接呼び出していません。
それでも、次の処理によってインスタンスを作成したときに、__init__が自動的に実行されます。
character = Character()__init__は、主にインスタンスの初期設定に使用します。
例えば、キャラクターの名前とHPを設定してみましょう。
class Character:
def __init__(self):
self.name = "スライム"
self.hp = 100
character = Character()
print(character.name)
print(character.hp)実行結果は次のとおりです。
スライム
100
インスタンスを作成した時点で、nameとhpという属性が自動的に設定されています。
なお、__init__の前後には、アンダースコアが2つずつ付いています。
__init__次のように、アンダースコアが1つだけではありません。
_init_入力するときは間違えないように注意しましょう。
selfとは
クラスを初めて学ぶときに、特に分かりにくいのがselfです。
selfは、作成されたインスタンス自身を表します。
次のコードを見てみましょう。
class Character:
def __init__(self):
self.name = "スライム"このコードのself.nameは、作成されたインスタンスが持つname属性を意味します。
character = Character()この場合、イメージとしては次のようになります。
character.name = "スライム"ただし、クラスを定義している時点では、インスタンスの変数名がcharacterになるとは限りません。
次のように、さまざまな変数名でインスタンスが作成される可能性があります。
character1 = Character()
enemy = Character()
player = Character()そのため、クラスの中では特定の変数名を使わず、インスタンス自身を表すselfを使用します。
self.nameselfは、メソッドの最初の引数として記述します。
def __init__(self):ただし、インスタンスを作るときに、selfに渡す値を指定する必要はありません。
character = Character()Pythonが自動的に、作成したインスタンスをselfに渡してくれます。
そのため、次のようには書きません。
character = Character(character)selfはクラスの中で使用する特別な変数だと考えておきましょう。
メソッドを定義する
クラスの中に定義された関数を、メソッドと呼びます。
通常の関数は、次のように定義します。
def hello():
print("こんにちは")クラスの中に関数を書くと、その関数はメソッドになります。
class Character:
def hello(self):
print("こんにちは")メソッドを呼び出すときは、インスタンス名とメソッド名をドットでつなぎます。
class Character:
def hello(self):
print("こんにちは")
character = Character()
character.hello()実行結果は次のとおりです。
こんにちは
メソッドの中では、selfを使ってインスタンスの属性にアクセスできます。
class Character:
def __init__(self):
self.name = "スライム"
def introduce(self):
print(f"私は{self.name}です")
character = Character()
character.introduce()実行結果は次のとおりです。
私はスライムです
introduceメソッドの中で、self.nameを使ってインスタンスの名前を取得しています。
クラスの中では、属性とメソッドをまとめて管理できます。
class Character:
def __init__(self):
self.name = "スライム"
self.hp = 100
def introduce(self):
print(f"名前は{self.name}です")
print(f"HPは{self.hp}です")このように、キャラクターに関するデータと処理を、1つのクラスにまとめられます。
引数を使ってインスタンスを作る
先ほどのクラスでは、どのインスタンスを作成しても、名前が「スライム」、HPが100になります。
class Character:
def __init__(self):
self.name = "スライム"
self.hp = 100異なる名前やHPを持つキャラクターを作るには、__init__に引数を追加します。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hpインスタンスを作るときに、名前とHPを渡します。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
character = Character("スライム", 100)
print(character.name)
print(character.hp)実行結果は次のとおりです。
スライム
100
次の部分で、Characterクラスに値を渡しています。
Character("スライム", 100)渡された値は、__init__のnameとhpで受け取ります。
def __init__(self, name, hp):そして、受け取った値をインスタンスの属性に代入します。
self.name = name
self.hp = hp左側と右側に似た名前が並んでいるため、最初は少し分かりにくいかもしれません。
self.name = name左側のself.nameは、インスタンスが持つ属性です。
右側のnameは、引数として受け取った値です。
つまり、次のような意味になります。
インスタンスのname属性 = 引数として受け取ったnameHPについても同じです。
self.hp = hp属性の値を変更する
インスタンスの属性は、作成後に変更できます。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
character = Character("スライム", 100)
character.hp = 80
print(character.hp)実行結果は次のとおりです。
80
また、メソッドを使って属性の値を変更することもできます。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
def damage(self, amount):
self.hp = self.hp - amount
character = Character("スライム", 100)
character.damage(30)
print(character.hp)実行結果は次のとおりです。
70
damageメソッドには、ダメージ量を表すamountを渡しています。
character.damage(30)メソッドの中では、現在のHPからダメージ量を引いています。
self.hp = self.hp - amountこの処理は、短く書くこともできます。
self.hp -= amountコード全体は次のようになります。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
def damage(self, amount):
self.hp -= amount
character = Character("スライム", 100)
character.damage(30)
print(character.hp)複数のインスタンスを作る
1つのクラスから、複数のインスタンスを作成できます。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
def introduce(self):
print(f"{self.name}のHPは{self.hp}です")
character1 = Character("スライム", 100)
character2 = Character("ドラゴン", 500)
character1.introduce()
character2.introduce()実行結果は次のとおりです。
スライムのHPは100です
ドラゴンのHPは500です
character1とcharacter2は、同じCharacterクラスから作られています。
しかし、それぞれ別のインスタンスであるため、異なる属性を持つことができます。
character1.nameには「スライム」が保存されています。
一方で、
character2.nameには「ドラゴン」が保存されています。
一方の属性を変更しても、もう一方の属性には影響しません。
character1.hp = 50
print(character1.hp)
print(character2.hp)実行結果は次のとおりです。
50
500
このように、クラスを使うことで、同じ種類のデータを効率よく管理できます。
クラスを使わない場合との違い
クラスを使わず、辞書を使ってキャラクターを管理することもできます。
character = {
"name": "スライム",
"hp": 100
}HPを減らす場合は、次のように書けます。
character["hp"] -= 30小さなプログラムであれば、辞書だけでも十分です。
しかし、データだけでなく処理も増えてくると、クラスを使ったほうが管理しやすくなります。
辞書では、データと関数を別々に定義することになります。
def damage(character, amount):
character["hp"] -= amountクラスを使う場合は、データと処理を同じ場所にまとめられます。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hp
def damage(self, amount):
self.hp -= amountクラスを使うと、どのデータに対する処理なのかが分かりやすくなります。
character.damage(30)クラスは、次のような場面でよく使われます。
- ゲームのキャラクターを管理する
- 商品情報を管理する
- ユーザー情報を管理する
- センサーや機器を管理する
- GUIの画面やボタンを管理する
- Webアプリケーションのデータを管理する
プログラムの規模が大きくなるほど、クラスを使う機会も増えていきます。
よくあるエラー
selfを書き忘れる
次のコードには、selfがありません。
class Character:
def introduce():
print("こんにちは")
character = Character()
character.introduce()このコードを実行すると、エラーが発生します。
インスタンスから呼び出すメソッドでは、第1引数にselfを記述します。
class Character:
def introduce(self):
print("こんにちは")属性にselfを付け忘れる
次のコードでは、nameにselfが付いていません。
class Character:
def __init__(self, name):
name = nameこれでは、インスタンスの属性として名前が保存されません。
正しくは次のように書きます。
class Character:
def __init__(self, name):
self.name = name__init__のスペルを間違える
次の書き方は間違いです。
def init(self):正しくは、前後にアンダースコアを2つずつ付けます。
def __init__(self):引数の数が合っていない
次のクラスでは、インスタンスを作るときにnameとhpを渡す必要があります。
class Character:
def __init__(self, name, hp):
self.name = name
self.hp = hpそのため、次の書き方ではエラーになります。
character = Character()必要な値を渡します。
character = Character("スライム", 100)インデントがずれている
クラスの中の処理には、インデントが必要です。
class Character:
def __init__(self, name):
self.name = name正しくは次のように書きます。
class Character:
def __init__(self, name):
self.name = nameメソッドの中の処理は、さらに1段階インデントします。
練習問題
最後に、クラスを使った簡単な練習問題に挑戦してみましょう。
練習問題1
次の情報を持つDogクラスを作成してください。
- 名前
- 年齢
また、名前と年齢を表示するintroduceメソッドを作成してください。
実行例は次のとおりです。
dog = Dog("ポチ", 3)
dog.introduce()実行結果は次のようにします。
名前はポチです
年齢は3歳です
解答例は次のとおりです。
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def introduce(self):
print(f"名前は{self.name}です")
print(f"年齢は{self.age}歳です")
dog = Dog("ポチ", 3)
dog.introduce()練習問題2
商品の名前と価格を管理するProductクラスを作成してください。
次の情報を属性として持たせます。
- 商品名
- 価格
また、商品情報を表示するshow_infoメソッドを作成してください。
product = Product("キーボード", 5000)
product.show_info()実行結果は次のようにします。
商品名:キーボード
価格:5000円
解答例は次のとおりです。
class Product:
def __init__(self, name, price):
self.name = name
self.price = price
def show_info(self):
print(f"商品名:{self.name}")
print(f"価格:{self.price}円")
product = Product("キーボード", 5000)
product.show_info()練習問題3
銀行口座を表すBankAccountクラスを作成してください。
次の機能を持たせます。
- 所有者名を保存する
- 残高を保存する
- 入金する
- 現在の残高を表示する
解答例は次のとおりです。
class BankAccount:
def __init__(self, owner, balance):
self.owner = owner
self.balance = balance
def deposit(self, amount):
self.balance += amount
def show_balance(self):
print(f"{self.owner}さんの残高は{self.balance}円です")
account = BankAccount("田中", 10000)
account.deposit(5000)
account.show_balance()実行結果は次のとおりです。
田中さんの残高は15000円です
まとめ
今回は、Pythonのクラスについて解説しました。
クラスは、データと処理をひとまとめにするための仕組みです。
今回の重要なポイントは、次のとおりです。
classを使ってクラスを定義する- クラスは設計図のようなもの
- クラスから作られたデータをインスタンスと呼ぶ
- インスタンスが持つデータを属性と呼ぶ
- クラスの中に定義した関数をメソッドと呼ぶ
__init__はインスタンス作成時に自動実行されるselfはインスタンス自身を表す- 1つのクラスから複数のインスタンスを作成できる
クラスは、Python入門の中でも大きな山場です。
最初からすべてを完璧に理解しようとすると、難しく感じてしまうかもしれません。
まずは、次の3つを覚えておきましょう。
クラスは設計図
インスタンスは設計図から作った実物
selfはインスタンス自身
実際にコードを書きながら、属性やメソッドを少しずつ追加していくと、クラスの仕組みが分かるようになります。
次回は、クラスの仕組みをさらに活用するために、継承やカプセル化などについて学んでいきます。


コメント