【Python】operatorの勉強(1)
PythonでGetter
とSetter
必要…?
まだまだペーペーです。プログラムだけでなく、文章に間違いや語弊がありましたらコメントなどで厳しく教えていただけたら幸いです。
きっかけ
他学科の友人の研究室に呼ばれ、プログラムを見て欲しいと頼まれた。
私「Pythonやってんだね」
友「なんもわからんけどね、卒論やばいから書いて欲しい」
私「おおん…頑張る…」
そんなこんなで、友人のプログラムを開発することになった私。
教授が書いてくれたという原型のプログラムを見ると、ものすごいJavaライクなプログラムが…
私「セッターとかゲッターって、Pythonだと意味なくね?」
友「なにそれおいしいの?」
私「おう…」
とはいったものの、これまで属性に直で値を代入していた自分。 「Javaみたいに、予期せぬ入力に対する処理とかどうすんだ?」と思ったので、調べてみた。
そして、自分の無知を知り恥じるのであった…
カプセル化
Pythonでpublic
とかprivate
を見たことがなかったので、カプセル化とかないと思っていた。
でもproperty
ってのがあるらしい。Google Style Guideに載っていたコードを引用したものが以下の通り。
import math class Square: def __init__(self, side: int): self.side = side @property def area(self): return self._get_area() def _get_area(self): return self.side ** 2 @area.setter def area(self, area): self._set_area(area) def _set_area(self, area): self.side = int(math.sqrt(area)) @property def perimeter(self): return self.side * 4 def main(): s1 = Square(3) print(s1.side, s1.area, s1.perimeter) # 3 9 12 s1.area = 25 print(s1.side, s1.area, s1.perimeter) # 5 25 20 s1.perimeter = 10 # Attribute Error if __name__ == '__main__': main()
このコードを噛み砕いて説明するとSquareクラスには属性が3つある。それは
- side(直接読み書きできる)
- area(メソッドを介して読み書きできる)
- perimeter(メソッドを介して、読みだけできる)
プロパティと関数の頭につけるだけで、属性のようにアクセスできる。
@area.setter
だけでなく、@area.getter
もあるが@property
と動作は同じ。@property
のみを設定すると、値の書き込みができなくなり、実質読み取り専用の属性を作ることができる。
感想
意図しない値の代入をdef
の中で防ぐことができる。(たとえば、areaに負の値が入ったらエラー表示とか)
研究で使うプログラムでそこまでの配慮は求められないが、今後書くプログラムには採用していきたい。
あんまり多用するとコードが読みづらくなりそうだし、使い方をよく考えないとな…