search
LoginSignup
4

More than 1 year has passed since last update.

posted at

updated at

Pythonの@propertyデコレータについてまとめる

大前提

class Man1():
    def __init__(self, name):
        self.name = name

このように定義するとインスタンス変数nameの参照、書き換え両方可能である。

# 初期化
Paul = Man("Paul")

# 参照可能
print(Paul.name)
# 書き換え可能
Paul.name = "Mac"

プライベート変数もどきを実現したい

しかし、あるインスタンス変数を

  • 必ずgetter/setter経由で参照/書き換えしたい
  • 参照は許すが書き換えは禁じたい

という場合がある。この場合、

# インスタタンス変数のprefixを__で定義(これにより__nameはマングリングされこの名前は参照できない)
class Man():
    def __init__(self, name):
        self.__name = name

    # この関数名は既存のインスタンス変数名と被ってはいけない
    @property
    def name(self):
        return self.__name

    # setterより前に同名のgetterの定義が必要
    # このsetterがないとnameプロパティは読み取り専用になる
    @name.setter
    def name(self, name):
        self.__name = name

とすることで

# 初期化
Paul = Man("Paul")

# 参照
# Paul.name()ではない
print(Paul.name)

# 書き換え
# Paul.name("Mac")ではない
Paul.name = "Mac"

# 元のpropertyに直接アクセス不可(エラー)
Paul.__name
Paul.__name = "Mac"

ただし、Paul._Man__nameでインスタンス変数__nameを参照、書き換えすることは可能(だからもどき)

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
4