TL;DR
クラスをもとに生成されたオブジェクトは インスタンス と呼ばれる。インスタンスが持つメソッド(クラスに紐づく処理。クラスやオブジェクトの中の関数)は インスタンスメソッド と呼ばれる。インスタンスごとに独立した値を保持する変数を、インスタンス変数 という。
インスタンスのポイント
- インスタンスを作ることで、クラスの中の関数を呼び出して処理させることができる
- インスタンスは、メソッドや変数を持つ
- 第一引数には必ずインスタンス自身のオブジェクトが渡される
- 第一引数に 慣例として self を指定する
インスタンス化までの構文を紐解くと、次のようになる。
class クラス名:
def __init__(self, 仮引数1, 仮引数2): # イニシャライザで初期化
self.インスタンス変数1 = 仮引数1 # インスタンス変数を定義
self.インスタンス変数2 = 仮引数2
def インスタンスメソッド(self, 仮引数1, 仮引数2):
処理
インスタンス名 = クラス名(実引数1, 実引数2) # インスタンスの生成
インスタンス名.インスタンスメソッド
名前 | 用語解説 |
---|---|
インスタンス | クラスをもとに生成されたオブジェクト |
インスタンスメソッド | インスタンスが持つメソッド |
インスタンス変数 | インスタンスが保持する変数 |
init | オブジェクトが作られたときに自動的に呼び出される |
self | インスタンス自身を参照する |
インスタンスの実引数に値を入れてみると次のようになる。
class クラス名:
def __init__(self, 引数1, 引数2):
self.インスタンス変数1 = 引数1
self.インスタンス変数2 = 引数2 * 10
インスタンス名 = クラス名("ポチ", 10)
print(f'{インスタンス名.インスタンス変数1}の体重は{インスタンス名.インスタンス変数2}kgです。')
# ポチの体重は100kgです。
インスタンス化
インスタンス化とはクラスオブジェクトに()をつけて呼び出し、インスタンスを作ることである。このとき、クラスオブジェクトに渡された引数はイニシャライザ(__init__
)によって初期化される。
インスタンスは関数と同じようにクラス名を呼び出して作る。
インスタンス名 = クラス名()
具体的には次のように使う。
class Menu: # クラスを定義する
pass # 処理
x = Menu() # インスタンス化
x.name = 'hello'
x.name
# 'hello'
type()メソッドでインスタンスのクラスを調べてみると __main__.Menu
と返される。isinstance()関数 で Menu クラスか調べると真、dir()関数で属性を調べると、__class__
が返されている。
class Menu:
pass
x = Menu()
x.name = 'hello'
type(x) # __main__.Menu
isinstance(x, Menu) # True
dir(x) # ['__class__', ...]
インスタンスメソッド
インスタンスが持つメソッドを、インスタンスメソッドと呼ぶ。インスタンスメソッドは、処理の中でインスタンス自身にアクセスできる。インスタンスを生成することで外からアクセスできる。
クラス定義の中でメソッドの第一引数が self になっていたら、インスタンスメソッドである。
メソッドのタイプを整理してみよう。
メソッドのタイプ | デコレータ | 第一引数 |
---|---|---|
インスタンスメソッド | なし | self |
クラスメソッド | @classmethod | cls |
静的メソッド | @staticmethod | オブジェクトやクラス以外 |
インスタンスメソッドは、最初 function クラスのインスタンスだが、
class Menu:
def hello(self):
print('hello')
type(Menu.hello)
# function
インスタンスを通じてアクセスすると method クラスになる。
class Menu:
def hello(self):
print('hello')
menu = Menu() # インスタンス
type(menu.hello)
# method
インスタンス変数
インスタンス変数とは、インスタンス(クラスをもとに生成されたオブジェクト)が保持する変数のことである。インスタンスごとに独立して扱うことができる。
class クラス名:
def __init__(self, 仮引数1, 仮引数2):
self.インスタンス変数1 = 仮引数1
self.インスタンス変数2 = 仮引数2
def インスタンスメソッド(self, 仮引数1, 仮引数2):
処理
インスタンス名 = クラス名(実引数1, 実引数2)
インスタンス名.インスタンスメソッド = 属性
インスタンスの属性(クラスやオブジェクトの変数のこと)に値を代入するとインスタンス変数を定義できる。オブジェクトを作る間、それらのものに属性を与えることができる。
class Menu:
def info(self):
print(self.name)
x = Menu() # インスタンス
x.name = 'hello'
x.info()
# hello
クラスは、属性を追加できる。
class Fruit:
color = 'red'
apple = Fruit()
Fruit.color # 'red'
apple.color # 'red'
インスタンスの属性を変更しても、クラスの属性は影響されない。
class Fruit:
color = 'red'
apple = Fruit()
apple.color = 'blue' # インスタンス属性を変更
apple.color # 'blue'
Fruit.color # 'red'
インスタンス定義後に、クラス属性を変更しても、インスタンスには影響を与えない。
class Fruit:
color = 'red'
apple = Fruit()
apple.color = 'blue'
Fruit.color = 'yellow' # クラス属性の変更
apple.color # 'blue' クラス属性に影響されない
しかし、クラス属性を変更したあとに、新しいオブジェクトを作ると影響を受ける。
class Fruit:
color = 'red'
apple = Fruit()
apple.color = 'blue'
Fruit.color = 'yellow' # クラス属性の変更
lemmon = Fruit() # 新しいオブジェクト追加
lemmon.color # 'yellow'
イニシャライザ
イニシャライザとは、オブジェクトが作られたときに自動的に呼び出される関数である。Python は、__init()__
を呼び出す前にすでにオブジェクトを構築している。したがって、__init()__
はコンストラクタ(インスタンスを作成したタイミングで実行されるメソッド)ではない。
class Dog:
def __init__(self, 仮引数1, 仮引数2):
self.name = 仮引数1
self.weight = 仮引数2
pochi = Dog("ポチ", 10)
print(f'{pochi.name}の体重は{pochi.weight}kgです。')
# ポチの体重は10kgです。
__init()__
は、インスタンスの生成直後に自動で呼び出され、このクラスのインスタンス全てが同じ属性を持つようになる。第一引数にインスタンス自身が渡る。第二引数の値も利用できる。
作成時にオブジェクトの属性に値を代入する場合、イニシャライザ(初期化子)のために、特殊メソッド __init()__
を記述する必要がある。
クラス定義で __init()__
を定義するときは、第一引数は self でなければならない。(self はインスタンス自身を表す仮引数名である)
全てのクラス定義が、__init()__
を持つ必要はない。