Pythonのクラスのプロパティ(property)について解説します。
Pythonのクラスのプロパティ
オブジェクト指向プログラミングの重要な概念はカプセル化です。カプセル化とは、外部から直接アクセスできないように変数を隠ぺいし、必要な情報だけを公開する仕組みです。これにより、意図しない変数の操作や予期しないバグを防ぐことが可能となります。
Pythonにおいてカプセル化に重要なものが「プロパティ(property)」です。この記事では、Pythonのクラスのプロパティついて紹介します。
プロパティとは
他の言語(C言語やJavaなど)では、get_xxx
やset_xxx
といったアクセサリーメソッドで変数の値を取得・設定することが一般的です。前者をゲッター、後者をセッターと言います。
一方で、Pythonではpropertyデコレータを使用することで、変数のように見えるが内部ではメソッドとして動作するプロパティを作成できます。これにより、より直感的なコードを書くことが可能です。
プロパティのためのメソッド定義は具体的には以下のようになります。
ゲッター:@propertyデコレータを記載する。
セッター:@<プロパティ名>.setterデコレータを記載する。
デコレータとはメソッドを装飾して機能を付与する仕組みです。デコレータの基本については「デコレータの基本的な使い方」を参考にしてください。
プロパティの基本的な使い方
ここからは具体的な例でプロパティの使い方を紹介します。
class Person: def __init__(self, first_name=None, last_name=None, age=None): self.__first_name = first_name self.__last_name = last_name self.__age = age @property def first_name(self): return self.__first_name @property def last_name(self): return self.__last_name @property def age(self): return self.__age @first_name.setter def first_name(self, value): self.__first_name = value @last_name.setter def last_name(self, value): self.__last_name = value @age.setter def age(self, value): if value >= 0: self.__age = value else: raise ValueError( "Only values greater than or equal to 0 are allowed." ) def myname(self): print(f"私の名前は、{self.__last_name}{self.__first_name}、{self.__age}歳です。") def main(): person1 = Person("太郎", "田中", 20) print(person1.first_name) print(person1.last_name) print(person1.age) person1.myname() print("===") person1.first_name = "次郎" person1.last_name = "佐藤" person1.age = 15 print(person1.first_name) print(person1.last_name) print(person1.age) person1.myname() if __name__ == "__main__": main()
【実行結果】 太郎 田中 20 私の名前は、田中太郎、20歳です。 === 次郎 佐藤 15 私の名前は、佐藤次郎、15歳です。
上記例では、インスタンス変数を「__
」(アンダースコア×2個)を付けた変数名としています。このような変数はPythonでは外部から直接参照できない変数となっています。
しかし、アクセス時には「person1.first_name
」、値の変更時には「person1.firstname = "次郎"
」のように直感的にアクセスできています。これは、プロパティによってゲッターとセッターに関するメソッドを定義しているためです。
ゲッターとセッターの定義
ゲッター
@property
デコレータを使って定義します。以下は、__first_name
の値を取得するゲッターのメソッド定義の部分です。
@property def first_name(self): return self.__first_name
セッター
@プロパティ名.setter
デコレータを使って定義します。値の設定時に追加のロジックを組み込むといったことも可能です。以下は、ageプロパティを取得する際に、年齢が0以上かどうかをチェックしています。
@age.setter def age(self, value): if value >= 0: self.__age = value else: raise ValueError( "Only values greater than or equal to 0 are allowed." )
プロパティのメリット
- 直感的な操作:
person.first_name
といった形で変数のようにアクセスできるため、コードの可読性が向上します。 - カプセル化:外部からの変数への直接アクセスを防ぎ、内部ロジックでコントロールできます。例えば、値の範囲をチェックするなどの追加機能も簡単に実装可能です。
まとめ
Pythonのクラスのプロパティについて解説しました。
Pythonのプロパティでは、カプセル化を簡単に実現し、外部からの直感的なアクセスを可能にするための強力な機能です。変数を隠ぺいしつつ、ゲッターとセッターを通じて安全にアクセスできるため、より堅牢で保守性の高いコードにすることができます。
Pythonにおけるクラス実装では、プロパティを使って適切に変数にアクセスできるようにしてください。
上記で紹介しているソースコードについてはgithubにて公開しています。参考にしていただければと思います。