お勉強したことメモ
主に私が良く使うC++と違う点についてハマった点とか、新しく学んだ事をつらつらとメモって置く。
- 結局、プロパティ(property)はディスクリプタ型の一部つーことらしい。
- __new__は__init__(コンストラクタ)より先に呼ばれる
- 親クラスのコンストラクタは明示的に呼ばないとだめ
- 親クラスのメソッドを明示的に呼ぶには、例えば下の例だと
- Parent.__init__(self)
- super(Child,self).__init__()
のどちらでも動作するが、最近の規格(new style class。objectを継承して書くクラス)だとsuper関数を使用したものが推奨されているぽい。逆に上のはold styleってこと。
- pep8, Pylintでコードの綺麗さチェックできる
↓適当に継承&プロパティ使ってみたコード
# -*- coding: utf-8 -*- class Parent(object): def __new__(cls): print("Parent new is called...") return object.__new__(cls) def __init__(self): self._val = 100 print("Parent init is called...") def _val_get(self): return self._val def _val_set(self,val): self._val = val def _val_delete(self): print("_val_delete is called") val = property(_val_get, _val_set, _val_delete, "The Value of parent(docstring)") def hello_world(self): print("Hello, world!") class Child(Parent): def __init__(self): super(Child,self).__init__() print("Child init is called") def hello_world(self): super(Child,self).hello_world() print("...and, child!") if(__name__ == "__main__"): instance = Parent() print instance.val instance.val = 333 print instance.val del instance.val print instance.__dict__ instance2 = Child() print instance2.hello_world()
実行結果
Parent new is called... Parent init is called... 100 333 _val_delete is called {'_val': 333} Parent new is called... Parent init is called... Child init is called Hello, world! ...and, child! None
propertyの書き方
上のpropertyの書き方は古いらしく、以下のようにデコレータ使って書くのが洒落オツらしい。
@propertyでgetterのみの定義、そこに@x.setterみたいにしてセッターやデリータも追加できる。
# -*- coding: utf-8 -*- class Hoge(object): def __init__(self, x): self._x = x @property def x(self): print 'call getter' return self._x @x.setter def x(self, x): print 'call setter' self._x = x @x.deleter def x(self): print 'call deleter' del self._x if(__name__ == "__main__"): hoge = Hoge(10) hoge.x = 100 print hoge.x del hoge.x |< 実行するとちゃんと値の設定・取得が出来ている事がわかる。 >|| call setter call getter 100 call deleter