1. ホーム 
  2. 備忘録 
  3. Python

プロパティ

プロパティ

クラス内で使用する変数を外部から勝手に書き換えてほしくない場合がある

Python ではプロパティという機能を使って上記を実現する

プロパティとはクラスのメンバで変数のように参照できる関数であり、インスタンス変数を取得・変更・削除するときに何かしらの処理を加えることができる機能である

プロパティについて例を以下に記載する

lesson.py

class Animal(object):
    def __init__(self, name, age=0):
        self._name = name
        self.age = age

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

cat = Animal('ミケ', 3)
cat.age = 10  # 書き換え可能
print(cat.name, cat.age)  # ミケ 10
cat.name = 'aaa'  # AttributeError: can't set attribute

実際に Animal クラスで設定した変数は _name だが、@property によって、cat.name が変数のように参照できるようになっている(ゲッターという)

ちなみに変数名に _(アンダースコア) をつける理由は外部から直接読み取れない変数であると明示的にするためである


また、その後 cat.name を書き換えようとしてみると AttributeError が発生している

このように、プロパティとして作成するとセッターを用意しない限り、書き込み不可となる

セッターの作り方は以下の通りである

lesson.py

class Animal(object):
    def __init__(self, name, age=0):
        self._name = name
        self.age = age

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

    @name.setter
    def name(self, cat_name):
        if len(cat_name) <= 6:
            self._name = cat_name
        else:
            raise ValueError

cat = Animal('ミケ', 3)
cat.age = 10  # 書き換え可能
print(cat.name, cat.age)  # ミケ 10
cat.name = 'ミケネコ'
print(cat.name, cat.age)  # ミケネコ 10
cat.name = 'ミケランジェロ'
print(cat.name, cat.age)  # ValueError

上記の通りセッターは @プロパティ名.setter というデコレータを付けることで実装できる

セッターを作成する前に当該プロパティのゲッターを用意しておかなければいけない


マングリング

変数名に _ をつけることで予測候補から外したり他のプログラマに外部からアクセスしないよう明示的に示したりできるが、実際は cat._name とアクセスすれば直接読み書きできてしまう

変数名に __ をつけることで、cat.__name では直接的に変数にアクセスできないようにすることができる

これをマングリングと言って実際には __ を付けることで属性名が _クラス名__識別子 の形に置換されている

そのため cat._Animal__name と書けば同様に読み書きできるが、誤って呼び出してしまうことは減る

ただし一般的にはプロパティを作る際の変数の隠蔽は _ のケースが多いので、知識として知っておくだけでよい