pythonのプロパティに関しての記事です。
__slots__
やコメント、型ヒントなどは省略しています。
あまり恩恵がわかりにくい例
1.インスタンス変数のみ
class Data:
def __init__(self):
self.x = "a"
2.プロパティで書いたパターン
class Data:
def __init__(self):
self._x = "a"
@property
def x(self):
return self._x
@x.setter
def x(self, arg_x):
self._x = arg_x
✴︎1 アンダースコア()は直接アクセスして欲しくない変数につけます。
より強固にする場合はアンダースコアを二つにする(_)
上記のクラスをどちらを使っても同じ結果になります
data = Data()
print(data.x)
data.x = "b"
print(data.x)
>>a
>>b
この二つの例だけでは恩恵がわかりにくいですが、いくつかのポイントに注目しておくと良いです。
1.プロパティでは直接値を保持するインスタンス変数をプロパティを介していじっている事
2.プロパティでは値を取得するまたはセットする場合に処理(確認)する構造を持たせやすいこと。
例1 自身が保持する値(設定)が、他の値に依存するパターン
まずはインスタンス変数のみでクラスを用意してみました。
class Lock:
"""
錠クラス
"""
def __init__(self):
self.word = ""
self.number = 0
self.input_state = {
"word": self.word,
"number": self.number
}
lock1 = Lock()
lock1.word = "a"
print(lock1.input_state)
>> {'word': '', 'number': 0}
wordに"a"を入れたのに、input_stateの"word"の値は変化していませんよね。
これはinput_stateは初期化時に値が決まってしまうため、"word"の値は更新されません。
(初期入力時だけ覚えこませる変数としてならありかも知れません。)
class Lock:
"""
錠クラス
"""
def __init__(self):
# 暗証番号
self.word = ""
self.number = 0
@property
def input_state(self):
return {
"word": self.word,
"number": self.number
}
lock1 = Lock()
lock1.word = "a"
print(lock1.input_state)
>> {'word': 'a', 'number': 0}
今度はwordが変更された時にinput_stateは更新されていますね。
例2 バリデイトしたい場合
今度はwordに"b"を入れるのは禁止にしたい場合を考えます。
class InvalidWordError(Exception):
pass
class Lock:
"""
錠クラス
"""
def __init__(self):
# 暗証番号
self._word = ""
self.number = 0
@property
def word(self):
return self._word
@word.setter
def word(self, arg):
if arg == "b":
raise InvalidWordError()
self._word = arg
@property
def input_state(self):
return {
"word": self.word,
"number": self.number
}
aを入力する場合
lock1 = Lock()
lock1.word = "a"
print(lock1.input_state)
>> {'word': 'a', 'number': 0}
bを入力する場合
lock1 = Lock()
lock1.word = "b"
print(lock1.input_state)
>Traceback (most recent call last):
> File "〇〇.py", line 39, in <module>
> lock1.word = "b"
> File "〇〇.py", line 23, in word
> raise InvalidWordError()
>〇〇.InvalidWordError
今回は無効な文字("b")が入った場合に例外を出す様にしています。
他の開発者がクラスを扱いやすくするための工夫は大事ですね。
またプロパティはカプセル化にも通じる話だと思うのでオブジェクト思考では欠かせない存在。。