pythonにおいてproperty()はどのように働くのでしょうか?(関数の内部で何が行われているのか)
この場合『内部で何が行われているか』より『どのようなことが起きるか』の方が大事です。
リファレンス を見ると、property関数の引数は次のようになっています。
class property(fget=None, fset=None, fdel=None, doc=None)
今回はfdelを与えていないので、試しに要素の削除を試みてみます。
Python
1i = Prop()
2i.x = 10
3print(i.x)
4
5del i.x
実行結果 Wandbox
plain
110
2Traceback (most recent call last):
3 File "prog.py", line 17, in <module>
4 del i.x
5AttributeError: can't delete attribute
属性が削除できなくなっていることが分かります。
それだとわざわざproperty()を設定した意味がなくなるような気がしてなりません。
前述のとおり、今回はfdelを指定しなかったことにより削除不可の属性ができました。
同様にfsetを指定しないと、読み取り専用の属性が作れます。
Python
1class Prop:
2 def __init__(self):
3 self.__x = 0
4
5 def getx(self):
6 return self.__x
7
8 x = property(getx)
9
10
11i = Prop()
12print(i.x)
13i.x = 10
14print(i.x)
実行結果 Wandbox
plain
10
2Traceback (most recent call last):
3 File "prog.py", line 13, in <module>
4 i.x = 10
5AttributeError: can't set attribute
どちらかと言うとこの目的でpropertyを利用することが多いです。
また、属性の読み取り/書き換えをフックできるので、
例えば不正な値の代入を防ぐ機能を簡単に付け加えることができます。
プロパティもどき
気付かないうちに質問の内容が挿げ替わっていたので。
こんなふうな実装なんじゃないでしょうかね。
Python
1class MyProperty:
2 def __init__(self, fget=None, fset=None):
3 self._fget = fget
4 self._fset = fset
5
6 def __get__(self, instance, owner):
7 if self._fget is None:
8 raise AttributeError("unreadable attribute")
9
10 return self._fget(instance)
11
12 def __set__(self, instance, value):
13 if self._fset is None:
14 raise AttributeError("can't set attribute")
15
16 self._fset(instance, value)
これを見て全然イメージが湧かないなら、細かな疑問は一回捨てて勉強を進めた方が良いです。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/10/06 14:12
2018/10/06 14:38