メインコンテンツへスキップ
  1. 第08講 クラス(1/2)/

クラス定義

クラス OOP インスタンス オブジェクト ドット記法 メソッド インスタンス変数 Self
目次

クラスとは
#

教科書 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 の変数 nameage にそれぞれ "John Doe"30 を代入しています.
  • 最後に,Person クラスで定義されている get_name メソッドと get_age メソッドを呼び出して結果を出力しています.
    • get_name メソッド,get_age それぞれのメソッドの中で self.nameself.age として,Person のインスタンス変数 nameage にアクセスしています.

ドット記法
#

クラス利用の例でも見たように,インスタンス変数やメソッドにアクセスする際には,ドットを利用します. このようなアクセス方法を ドット記法 と呼びます.

インスタンス名.インスタンス変数名
インスタンス名.メソッド名(引数リスト)

複数のインスタンス(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.

p1p2はともに Person オブジェクトですが,それぞれ別の nameage という変数を持っています. 同様に,get_nameget_ageprint メソッドもそれぞれのオブジェクトに紐づいています. そのため,どのオブジェクトに対して,メソッドを呼び出したかによって,結果が異なります.

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.")

参考
#