とほほのPython入門 - クラス

トップ > Python入門 > クラス

目次

クラス(class)

Python の クラス(class)は次のように定義します。クラス名は慣習的に大文字で始めます。

Python
class MyClass:
    """A simple example class"""         # 三重クォートによるコメント

    def __init__(self):                  # コンストラクタ
        self.name = ""

    def getName(self):                   # getName()メソッド
        return self.name

    def setName(self, name):             # setName()メソッド
        self.name = name

a = MyClass()                            # クラスのインスタンスを生成
a.setName("Tanaka")                      # setName()メソッドをコール
print(a.getName())                       # getName()メソッドをコール

クラス定義の冒頭には、"""...""" で ドキュメントストリング を記述することができます。

Python
def MyClass:
    """A sample class"""
    (略)

クラス変数・インスタンス変数(attribute)

クラスは、インスタンス変数クラス変数 を持つことができます。インスタンス変数は「インスタンス.変数名」で表され、インスタンス毎に独立の変数です。コンストラクタ __init__(後述)の中で初期化することをお勧めします。

Python
class MyClass:
    def __init__(self):
        self.name = ""              # インスタンス変数

a1 = MyClass()
a1.name = "Tanaka"

a2 = MyClass()
a2.name = "Suzuki"

print(a1.name)                       #=> Tanaka
print(a2.name)                       #=> Suzuki

クラス変数は「クラス名.変数名」で表され、すべてのインスタンスで共通の変数です。

Python
class MyClass:
    PI = 3.14                        #=> クラス変数

print(MyClass.PI)                    #=> 3.14

下記は、クラス変数を用いてインスタンスの個数をカウントアップするサンプルです。

Python
class MyClass:
    count = 0                       # クラス変数を初期化

    def __init__(self):
        MyClass.count += 1          # クラス変数をカウントアップ

a1 = MyClass()
a2 = MyClass()
print(MyClass.count)                #=> 2

クラス変数やインスタンス変数は、動的に追加することができます。

Python
class MyClass:
    pass

a1 = MyClass()
a1.name2 = "Tanaka"                 # インスタンス変数の追加
MyClass.PI2 = 3.141593              # クラス変数の追加

インスタンス変数が存在しない場合、「インスタンス.変数名」はクラス変数を参照することに注意してください。「インスタンス.変数名」に値を代入した時点でインスタンス変数が生成され、以降はインスタンス変数が参照されます。

Python
class MyClass:
    PI = 3.14

a1 = MyClass()
a2 = MyClass()
print(a1.PI)                        # クラス変数 MyClass.PI(3.14) が参照される
a1.PI = 3.141593                    # インスタンス変数 a1.PI が生成される
print(a1.PI)                        # インスタンス変数 a1.PI(3.141593)が参照される
print(a2.PI)                        # クラス変数 MyClass.PI(3.14) が参照される

Python では private や protected などのスコープを制御する機構は実装されておらず、クラス変数、インスタンス変数はすべてどこからでも参照可能(public)となります。

メソッド(method)

クラスが持つ関数は メソッド と呼ばれます。メソッドもまた、どこからでも参照可能(public)です。メソッドの第一引数には、クラスのインスタンスを指定し、第二引数以降で、メソッドの引数を受け取ります。

Python
class MyClass:
    name = ""
    def setName(self, name):     # 第一引数は自インスタンス(self)
        self.name = name

a = MyClass()
a.setName("Tanaka")

アクセス制限(_, __)

Python では private や protected などのアクセス修飾子はサポートされていません。アンダーバー(_)で始まる変数や関数は外から参照しないという慣習的ルールがあります。アンダーバー2個(__)で始まる変数や関数は参照が制限されます。

Python
class MyClass:
    def __init__(self):
        self.name = "tanaka"
        self._name = "yamada"
        self.__name = "suzuki"

    def hello(self): print('hello')
    def _hello(self): print('hello')
    def __hello(self): print('hello')

a = MyClass()

print(a.name)           # 参照できる
print(a._name)          # 参照できるが慣習的に参照しない
# print(a.__name)       # 参照できない(AttributeError例外)

a.hello()               # 参照できる
a._hello()              # 参照できるが慣習的に参照しない
# a.__hello()           # 参照できない(AttributeError例外)

とは言っても、__ で始まる変数や関数も、_クラス名__変数名 に名前変換されるだけで、下記の様にするとアクセスできてしまうそうです。

Python
print(a._MyClass__name)
a._MyClass__hello()

コンストラクタ(__init__)

__init__() メソッドは、クラスのインスタンスが生成された際に呼び出されます。コンストラクタ とも呼ばれます。

Python
class MyClass:
    def __init__(self, name):
        self.name = name
    def getName(self):
        return self.name

a = MyClass("Tanaka")
print(a.getName())                     #=> Tanaka

デストラクタ(__del__)

__del__() メソッドは、クラスのインスタンスが消滅する際に呼び出されます。デストラクタ とも呼ばれます。

Python
class MyClass:
    def __init__(self):
        print("INIT!")
    def __del__(self):
        print("DEL!")

a = MyClass()           #=> INIT!
del a                   #=> DEL!

文字列化(__str__)

__str__() は、インスタンスを暗黙的に文字列に変換する際の変換処理を定義します。

Python
class MyClass:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return "My name is " + self.name

a = MyClass("Yamada")
print(a)                       #=> My name is Yamada

継承(inheritance)

他のオブジェクト指向言語と同様、クラスを継承することもできます。下記の例では、MyClassクラスを継承した、MyClass2サブクラスを定義しています。サブクラスでは、親クラスが持つアトリビュートやメソッドを継承して利用することができます。

Python
class MyClass:
    def hello(self):
        print("Hello")

class MyClass2(MyClass):
    def world(self):
        print("World")

a = MyClass2()
a.hello()                   #=> Hello
a.world()                   #=> World

サブクラスでは、親クラスのメソッドを上書き(オーバーライド)することができます。

Python
class MyClass:
    def hello(self):
        print("Hello")

class MyClass2(MyClass):
    def hello(self):        # 親クラスのhello()メソッドをオーバーライド
        print("HELLO")

a = MyClass2()
a.hello()                   #=> HELLO

親クラス(super())

super()親クラス を参照します。第一引数にはクラス、第二引数にはインスタンスを指定します。下記の例では、サブクラスのコンストラクタの中で、親クラスのコンストラクタを呼び出しています。

Python
class MyClass1(object):
    def __init__(self):
       self.val1 = 123

class MyClass2(MyClass1):
    def __init__(self):
        super(MyClass2, self).__init__()
        self.val2 = 456

a = MyClass2()
print(a.val1)               #=> 123
print(a.val2)               #=> 456

多重継承

Python では多重継承がサポートされています。下記では、MyClassA, MyClassB 両方を継承する MyClassC を定義しています。

Python
class MyClassA:
    def funcA(self):
        print("MyClassA:funcA")

class MyClassB:
    def funcB(self):
        print("MyClassB:funcB")

class MyClassC(MyClassA, MyClassB):
    pass

a = MyClassC()
a.funcA()                    # MyClassA のメソッドも
a.funcB()                    # MyClassB のメソッドも使用できる

クラス階層

Python のクラスはすべて、object をルートとするクラス階層を構成しています。

Python
object
 +- int
 |   +- bool
 +- long
 +- float
 +- complex
 +- basestring
 |   +- str
 |   +- unicode
 +- list
 +- tuple
 +- dict
 +- file
 +- BaseException
     +- SystemExit
     +- KeyboardInterrupt
     +- GeneratorExit
     +- Exception
         +- StopIteration
         +- StandardError
         |   +- BufferError
         |   +- ArithmeticError
         |   |   +- FloatingPointError
         |   |   +- OverflowError
         |   |   +- ZeroDivisionError
         |   +- AssertionError
         |   +- AttributeError
         |   +- EnvironmentError
         |   |   +- IOError
         |   |   +- OSError
         |   |       +- WindowsError (Windows)
         |   |       +- VMSError (VMS)
         |   +- EOFError
         |   +- ImportError
         |   +- LookupError
         |   |   +- IndexError
         |   |   +- KeyError
         |   +- MemoryError
         |   +- NameError
         |   |   +- UnboundLocalError
         |   +- ReferenceError
         |   +- RuntimeError
         |   |   +- NotImplementedError
         |   +- SyntaxError
         |   |   +- IndentationError
         |   |       +- TabError
         |   +- SystemError
         |   +- TypeError
         |   +- ValueError
         |       +- UnicodeError
         |           +- UnicodeDecodeError
         |           +- UnicodeEncodeError
         |           +- UnicodeTranslateError
         +- Warning
             +- DeprecationWarning
             +- PendingDeprecationWarning
             +- RuntimeWarning
             +- SyntaxWarning
             +- UserWarning
             +- FutureWarning
             +- ImportWarning
             +- UnicodeWarning
             +- BytesWarning

Copyright(C) 2014-2022 杜甫々
初版:2014年12月30日、最終更新:2022年10月9日
http://www.tohoho-web.com/python/class.html