お勉強したことメモ

主に私が良く使う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