Pythonのクラス入門|定義から継承までの基本
Pythonのクラスは、データとそれを操作する処理をひとまとめにする仕組みです。プログラムの規模が大きくなると、関連するデータと関数をまとめて管理したくなります。この記事では、クラスの基本的な定義方法から__init__メソッド、インスタンスの作成、継承まで、初心者がつまずきやすいポイントを押さえながら解説します。
クラスとは何か
クラスは、オブジェクトの「設計図」にあたるものです。設計図(クラス)からは同じ構造を持つ複数の実体(インスタンス)を作り出すことができます。
クラスとインスタンスの関係
たとえば「犬」というクラスがあれば、「ポチ」「ハチ」といった具体的な犬がインスタンスです。
# クラスを定義する
class Dog:
pass # まだ中身は空
# インスタンスを作成する
pochi = Dog()
hachi = Dog()
print(type(pochi)) # <class '__main__.Dog'>
print(pochi is hachi) # False(別のインスタンス)
Dog()と書くことでDogクラスのインスタンスが1つ作られます。pochiとhachiは同じDogクラスから作られていますが、それぞれ別のオブジェクトです。
なぜクラスを使うのか
関数と変数だけでもプログラムは書けますが、クラスを使うと次のような利点があります。
- 関連するデータと処理をまとめて管理できる
- 同じ構造のオブジェクトを何個でも作れる
- 継承を使ってコードの再利用ができる
__init__メソッドで初期化する
__init__メソッドは、インスタンスが作られるときに自動で呼ばれる特殊なメソッドです。インスタンスの初期値を設定するために使います。
__init__の基本
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
# インスタンス作成時に引数を渡す
pochi = Dog("ポチ", 3)
print(pochi.name) # ポチ
print(pochi.age) # 3
Dog("ポチ", 3)と書くと、Pythonが内部で__init__(self, "ポチ", 3)を自動的に呼び出します。
selfとは何か
selfは、作成されるインスタンス自身を指す変数です。クラス内のメソッドの第1引数は必ずselfにします。
class Dog:
def __init__(self, name):
# self.name はインスタンスの属性
# name は __init__ に渡された引数
self.name = name
pochi = Dog("ポチ")
hachi = Dog("ハチ")
# それぞれのインスタンスが独自のnameを持つ
print(pochi.name) # ポチ
print(hachi.name) # ハチ
self.name = nameは「このインスタンスのname属性に、引数で受け取ったnameの値を設定する」という意味です。
デフォルト値を持つ引数
class Dog:
def __init__(self, name, age=0, breed="雑種"):
self.name = name
self.age = age
self.breed = breed
# ageとbreedを省略するとデフォルト値が使われる
dog1 = Dog("ポチ")
print(dog1.age) # 0
print(dog1.breed) # 雑種
# 明示的に指定する
dog2 = Dog("ハチ", age=5, breed="秋田犬")
print(dog2.breed) # 秋田犬
メソッドを定義する
クラス内に定義する関数を「メソッド」と呼びます。メソッドを使うことで、インスタンスが持つデータに対する操作をまとめて定義できます。
メソッドの基本
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
return f"{self.name}:ワンワン!"
def get_info(self):
return f"{self.name}({self.age}歳)"
pochi = Dog("ポチ", 3)
print(pochi.bark()) # ポチ:ワンワン!
print(pochi.get_info()) # ポチ(3歳)
メソッドの第1引数は必ずselfです。呼び出すときはpochi.bark()のように書き、selfは自動的に渡されます。
インスタンスの状態を変更するメソッド
class BankAccount:
def __init__(self, owner, balance=0):
self.owner = owner
self.balance = balance
def deposit(self, amount):
if amount <= 0:
print("入金額は正の数を指定してください")
return
self.balance += amount
print(f"{amount}円を入金しました。残高: {self.balance}円")
def withdraw(self, amount):
if amount > self.balance:
print("残高が不足しています")
return
self.balance -= amount
print(f"{amount}円を出金しました。残高: {self.balance}円")
account = BankAccount("田中", 1000)
account.deposit(5000) # 5000円を入金しました。残高: 6000円
account.withdraw(2000) # 2000円を出金しました。残高: 4000円
account.withdraw(10000) # 残高が不足しています
__str__メソッドで表示をカスタマイズ
__str__メソッドを定義すると、print()で出力したときの表示をカスタマイズできます。
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Dog({self.name}, {self.age}歳)"
pochi = Dog("ポチ", 3)
print(pochi) # Dog(ポチ, 3歳)
__str__を定義していない場合、print(pochi)は<__main__.Dog object at 0x...>のようなわかりにくい表示になります。
クラス変数とインスタンス変数
クラスにはクラス変数とインスタンス変数の2種類の変数があります。
クラス変数
クラス変数は、すべてのインスタンスで共有される変数です。
class Dog:
species = "犬" # クラス変数
def __init__(self, name):
self.name = name # インスタンス変数
pochi = Dog("ポチ")
hachi = Dog("ハチ")
# クラス変数はすべてのインスタンスで共有
print(pochi.species) # 犬
print(hachi.species) # 犬
print(Dog.species) # 犬
# インスタンス変数はそれぞれ独立
print(pochi.name) # ポチ
print(hachi.name) # ハチ
インスタンス数をカウントする例
class Dog:
count = 0 # クラス変数: インスタンス数を管理
def __init__(self, name):
self.name = name
Dog.count += 1 # インスタンスが作られるたびに加算
dog1 = Dog("ポチ")
dog2 = Dog("ハチ")
dog3 = Dog("タロウ")
print(Dog.count) # 3
継承の基本
継承を使うと、既存のクラス(親クラス)の機能を引き継いだ新しいクラス(子クラス)を作ることができます。
継承の書き方
# 親クラス
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
return f"{self.name}が鳴いています"
# 子クラス(Animalを継承)
class Dog(Animal):
def speak(self):
return f"{self.name}:ワンワン!"
class Cat(Animal):
def speak(self):
return f"{self.name}:ニャー!"
dog = Dog("ポチ")
cat = Cat("タマ")
print(dog.speak()) # ポチ:ワンワン!
print(cat.speak()) # タマ:ニャー!
class Dog(Animal):のように、括弧の中に親クラスを書くと継承になります。子クラスは親クラスのメソッドをそのまま使えるほか、同名のメソッドを定義すれば上書き(オーバーライド)できます。
superで親クラスのメソッドを呼ぶ
子クラスで__init__を拡張したいとき、super()を使って親クラスの__init__を呼び出します。
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
class Dog(Animal):
def __init__(self, name, age, breed):
super().__init__(name, age) # 親クラスの__init__を呼ぶ
self.breed = breed # 子クラス独自の属性
def get_info(self):
return f"{self.name}({self.breed}、{self.age}歳)"
pochi = Dog("ポチ", 3, "柴犬")
print(pochi.get_info()) # ポチ(柴犬、3歳)
print(pochi.name) # ポチ(親クラスの属性にもアクセス可能)
super().__init__(name, age)を書き忘れると、親クラスの初期化が行われずself.nameやself.ageが存在しなくなるので注意してください。
isinstanceで型を確認する
pochi = Dog("ポチ", 3, "柴犬")
print(isinstance(pochi, Dog)) # True
print(isinstance(pochi, Animal)) # True(親クラスにも該当する)
print(isinstance(pochi, Cat)) # False
継承関係にあるクラスでは、isinstanceは親クラスに対してもTrueを返します。
まとめ
Pythonのクラスについて、基本的な概念から継承までを解説しました。
- クラスはオブジェクトの設計図で、インスタンスは設計図から作られた実体
__init__メソッドでインスタンスの初期値を設定するselfはインスタンス自身を指す- メソッドはクラス内に定義する関数で、第1引数は必ず
self - クラス変数は全インスタンスで共有、インスタンス変数は個別に保持
- 継承を使って親クラスの機能を引き継いだ子クラスを作れる
super()で親クラスのメソッドを呼び出す
まずはシンプルなクラスを自分で定義して、インスタンスを作成する流れに慣れてください。関数だけで書いていたコードをクラスで整理してみると、クラスの便利さが実感できます。