趣味のPython・深層学習

中級者のための実装集

property, getter, setter 基礎

Pythonのプロパティ、ゲッター、セッターの基礎から応用まで

Pythonにおいて、プロパティ、ゲッター、セッターは、クラスのデータ属性をカプセル化し、適切にアクセスやデータの検証を行うための仕組みです。この仕組みを適切に使用することで、クラスのデータ属性に対するアクセスをコントロールし、コードの信頼性と保守性を高めることができます。 このブログ記事では、Pythonのプロパティ、ゲッター、セッターについて、基礎から応用まで、視覚的かつ丁寧に解説していきます。

プロパティ (Property) とは

プロパティとは、クラスの属性にアクセスするための特別なメソッドです。プロパティを使用することで、属性の値を直接取得または設定するのではなく、ゲッターとセッターを介して値を取得または設定することができます。これにより、属性の値の検証や変更を制御することができます。 プロパティのイメージは以下のようになります。

+---------------------+
|        Person       |
|  +------------------+
|  | _name (データ属性)|
|  +------------------+
|  | @property        |
|  | def name(self):  |  ゲッター
|  |     ...          |
|  +------------------+
|  | @name.setter     |
|  | def name(self,   |
|  |          value): |  セッター
|  |     ...          |
|  +------------------+
+---------------------+

ゲッタープロパティ (Getter Property)

ゲッタープロパティは、属性の値を取得するメソッドです。@propertyデコレータを使用して定義します。

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

上記の例では、name()メソッドがゲッタープロパティとして定義されています。このメソッドは、_nameデータ属性の値を返します。ゲッタープロパティは、属性の値を取得する際に使用されます。

person = Person("Alice")
print(person.name)  # 出力: Alice

セッタープロパティ (Setter Property)

セッタープロパティは、属性の値を設定するメソッドです。@property_name.setterデコレータを使用して定義します。

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise TypeError("名前は文字列である必要があります")
        self._name = value

上記の例では、name()メソッドがセッタープロパティとして定義されています。このメソッドは、_nameデータ属性の値を設定します。また、値が文字列でない場合はTypeErrorを発生させます。セッタープロパティは、属性の値を設定する際に使用されます。

person = Person("Alice")
person.name = "Bob"  # 値を設定
print(person.name)  # 出力: Bob

person.name = 123  # TypeError: 名前は文字列である必要があります

デリーター (Deleter) デリーターは、属性を削除するメソッドです。@property_name.deleterデコレータを使用して定義します。

class Person:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise TypeError("名前は文字列である必要があります")
        self._name = value

    @name.deleter
    def name(self):
        del self._name

上記の例では、name()メソッドがデリーターとして定義されています。このメソッドは、_nameデータ属性を削除します。デリーターは、属性を削除する際に使用されます。

person = Person("Alice")
print(person.name)  # 出力: Alice

del person.name
print(person.name)  # AttributeError: 'Person' object has no attribute '_name'

プロパティの利点 プロパティを使用することで、以下のような利点があります。

データの検証: セッタープロパティを使用することで、属性の値を検証し、不正な値の設定を防ぐことができます。 データの計算: ゲッタープロパティを使用することで、属性の値を計算して返すことができます。 カプセル化の強化: データ属性をアンダースコア (_name) で始めることで、外部からのアクセスを制限できます。 コードの可読性の向上: プロパティを使用することで、属性の取得や設定の処理を明確に分離できます。

ゲッターとセッターの従来の方法 プロパティの導入以前は、ゲッターとセッターを手動で実装する必要がありました。以下は、その従来の方法の例です。

class Person:
    def __init__(self, name):
        self._name = name

    def get_name(self):
        return self._name

    def set_name(self, value):
        if not isinstance(value, str):
            raise TypeError("名前は文字列である必要があります")
        self._name = value

上記の例では、get_name()メソッドがゲッター、set_name()メソッドがセッターとして実装されています。この方法では、属性の取得や設定の際に、明示的にメソッドを呼び出す必要があります。

person = Person("Alice")
print(person.get_name())  # 出力: Alice

person.set_name("Bob")
print(person.get_name())  # 出力: Bob

person.set_name(123)  # TypeError: 名前は文字列である必要があります

プロパティを使用すると、属性のように簡単にアクセスできるため、コードがより読みやすく、保守性が高まります。