クラスとは #
教科書 p.212(Lesson 8)プログラムが複雑になってくると,関数とそれに関するデータをまとめて扱いたくなります. そのために,Python では クラス(Class) という概念が用意されています. クラスは,関数とデータをまとめたもので,オブジェクト指向プログラミング(OOP; Object-Oriented Programming)の基本的な概念です.
なお,クラスは内部に関数や変数を含む大きな変数の定義に相当し,利用するには実体化(インスタンス化; instantiation)が必要です. この作成された実体(インスタンス; instance)のことを オブジェクト(Object) と呼びます.
クラスを定義する #
クラスには,変数,関数を含められます.
クラスを定義するには,class
キーワードを使います.
クラスの中身はインデントし,変数と関数を定義していきます.
クラスに含まれる関数は,最初の引数が self
になっています.
self
は,そのクラスのインスタンスを指します.
このような関数(クラスに含まれる関数のこと)を メソッド(Method) と呼びます.
また,クラスで定義される変数は,self.変数名
として利用できます.
このような変数のことを インスタンス変数(instance variable) と呼びます.
クラス内のメソッドとインスタンス変数は,クラスのインスタンス(オブジェクト)を通じてアクセスできます. また,両者の名前の重複は許されず,あとから代入されたものが優先されます.
クラス利用の例 #
class Person:
def get_name(self): # get_name は Person クラスのメソッド
return self.name # name は Person クラスのインスタンスに紐づいた変数
def get_age(self): # get_age は Person クラスのメソッド
return self.age # age も name と同じく,Person クラスのインスタンスに紐づいた変数
p = Person() # Person クラスをインスタンス化して(Personオブジェクトを作成して)
# p に Person クラスのインスタンス(Person オブジェクト)を代入する.
p.name = "John Doe" # Person オブジェクト p の変数 name に "John Doe" を代入する.
p.age = 30 # Person オブジェクト p の変数 age に 30 を代入する.
print(f"{p.get_name()} is {p.get_age()} years old.")
実行結果 #
$ python3 person.py
John Doe is 30 years old.
- このプログラムでは,
Person
クラスを定義し,get_name
メソッドとget_age
メソッドを定義しています. - 続いて,
Person
クラスをインスタンス化してp
に Person クラスのインスタンス(Personオブジェクト)を代入します. - そして,Personオブジェクトである
p
の変数name
とage
にそれぞれ"John Doe"
と30
を代入しています. - 最後に,
Person
クラスで定義されているget_name
メソッドとget_age
メソッドを呼び出して結果を出力しています.get_name
メソッド,get_age
それぞれのメソッドの中でself.name
とself.age
として,Person
のインスタンス変数name
とage
にアクセスしています.
ドット記法 #
クラス利用の例でも見たように,インスタンス変数やメソッドにアクセスする際には,ドットを利用します. このようなアクセス方法を ドット記法 と呼びます.
インスタンス名.インスタンス変数名
インスタンス名.メソッド名(引数リスト)
複数のインスタンス(Multiple Instances) #
クラスを複数回インスタンス化することで,複数のオブジェクトを作成できます. それぞれのオブジェクトは互いに影響せず,独立して動作します.
class Person:
def get_name(self):
return self.name
def get_age(self):
return self.age
def print(self): # 自分自身の情報を出力するメソッド(関数ではない)
print(f"{self.get_name()} is {self.get_age()} years old.")
def print_person(p): # Person を受け取り,その情報を出力する関数(メソッドではない)
print(f"{p.get_name()} is {p.get_age()} years old.")
p1 = Person() # 1つ目の Person オブジェクトを作成する.
p1.name = "John Doe" # p1 の name に "John Doe" を代入する.
p1.age = 30
p2 = Person() # 2つ目の Person オブジェクトを作成する.
p2.name = "Jane Doe" # p2 の name に "Jane Doe" を代入する.
p2.age = 35
# p1 の print メソッドを用いて,p1 の情報を出力する.
p1.print() # => John Doe is 30 years old.
# p2 の print メソッドを用いて,p2 の情報を出力する.
p2.print() # => Jane Doe is 35 years old.
# print_person 関数を呼び出し,p1 の情報を出力する.
print_person(p1) # => John Doe is 30 years old.
# print_person 関数を呼び出し,p2 の情報を出力する.
print_person(p2) # => Jane Doe is 35 years old.
p1
,p2
はともに Person
オブジェクトですが,それぞれ別の name
,age
という変数を持っています.
同様に,get_name
,get_age
,print
メソッドもそれぞれのオブジェクトに紐づいています.
そのため,どのオブジェクトに対して,メソッドを呼び出したかによって,結果が異なります.
self
#
self
は習慣的に,そのクラスのインスタンスを指す変数の名前として使われます.
習慣的に,ですので,別の名前でも構いません.
ただし,self
以外の名前を使うと,他のプログラマが混乱する可能性があるため,self
を使うことが推奨されます.
class Person:
def get_name(s): # self という名前でなくても良い.
return s.name # この場合,s という名前でインスタンス変数を利用する.
# return name # s という名前を省略すると,単なるローカル変数として扱われる.
# # そのような変数はないので,エラーになる.
def get_age(self):
return self.age
p = Person()
p.name = "John Doe"
p.age = 30
print(f"{p.get_name()} is {p.get_age()} years old.")