class
キーワードを使って、Python のクラスを定義することができます。
コンストラクタとインスタンスメソッド
メソッドは通常の関数と同様に def
キーワードで定義していくのですが、__init__
という名前のメソッドを定義すると、インスタンス生成時(クラス名()
)に呼び出されるコンストラクタとして扱われます。
コンストラクタの中では、自分自身のインスタンスを参照するための self
を使って、属性の初期化などを行います。
コンストラクタやメソッドの第 1 引数には、必ず自分自身のインスタンスを参照するための self
引数を配置します。
実際には、名前は何でもよいのですが、公式のスタイルガイドで self
という名前を使うことが推奨されています(参考: PEP 8)。
上記のように定義したクラスは、次のように使用することができます。
クラス属性 (class attribute)
クラス属性 は、インスタンスを生成せずにアクセスできる属性です。
次のクラスは、num
というクラス属性を持っています。
クラス属性には、クラス名.クラス属性名
という形でアクセスできます。
クラス定数も同様に定義できます。 名前を大文字にするだけです。
クラスメソッド (class method)
クラスメソッド は、インスタンスを生成せずに呼び出せるメソッドで、@classmethod
デコレーターを使って定義します。
クラスメソッドの第 1 引数には、自身のクラスメソッドを示す cls
を配置します(この名前も、PEP 8 で推奨されています)。
クラスメソッドの中からは、cls.クラス属性名
という形で、クラス属性にアクセスできます。
クラスメソッドは、ファクトリーメソッドの実装に使われることがあります。
次の mysterios_person
メソッドは、特殊な Person
インスタンスを生成するためのファクトリーメソッドです。
class Person:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
@classmethod
def mysterious_person(cls) -> "Person":
return cls(name="John Doe", age=20)
# 使用例: ファクトリーメソッドでインスタンス生成
person = Person.mysterious_person()
静的メソッド (static method)
静的メソッド は、インスタンスを生成せずに呼び出せるメソッドで、@staticmethod
デコレーターを使って定義します。
静的メソッドはクラスメソッドと異なり、第 1 引数で cls
を受け取りません。
単なる関数とほぼ同等ですが、クラス内で静的メソッドとして定義することにより、そのクラスに関連するユーティリティ関数であることが明確になります。
また、クラスをインポートするだけで静的メソッドにアクセスできるようになるなどの利点もあります。
class Formatter:
# ...
@staticmethod
def make_indent(level: int) -> str:
return " " * 4 * level
メソッドや属性を private にする
クラス内のメソッドや属性を private 扱いにするには、メソッド名の前にアンダースコア _
を 1 つ付けます。
ただし、これは単なる慣習で、実際には外からアクセスできてしまいます。
class Person:
def __init__(self, name: str, age: int):
self._name = name
self._age = age
if __name__ == "__main__":
p = Person("Maku", 14)
print(p._name) # 見えちゃう
print(p._age) # 見えちゃう
外からアクセスできないようにするには、メソッド名の前にアンダースコアを 2 つ付けます。
class Person:
def __init__(self, name: str, age: int):
self.__name = name
self.__age = age
if __name__ == "__main__":
p = Person("Maku", 14)
print(p.__name) # エラー!
print(p.__age) # エラー!
_クラス名__属性名
という名前に置き換えます。
この仕組みにより、外部からの不用意なアクセスを避けるとともに、サブクラスで定義された属性の名前との衝突を防ぐ効果があります。