2010年10月24日日曜日

Python組み込み関数(property関数)

クラス・インスタンスのプロパティ属性の取得・設定を行う組み込み関数
関数パラメーター property(fget=None, fset=None, fdel=None, doc=None)

    fget プロパティを取得するメソッド名
    fset プロパティを設定するメソッド名
    fdel プロパティを削除するメソッド名
    doc  プロパティの説明文
まず property関数を使わない使用例を示す。
>>> class Cal(object):
...    def __init__(self):
...        self.__x = None
...    def getx(self):
...        return self.__x
...    def setx(self, value):
...        self.__x = value
...    def delx(self):
...        del self.__x
...
>>> a = Cal()
>>> a.setx(10)
>>> a.getx()
10
次に property関数を使った使用例を示す。
>>> class Cal(object):
...    def __init__(self):
...        self.__x = None
...    def getx(self):
...        return self.__x
...    def setx(self, value):
...        self.__x = value
...    def delx(self):
...        del self.__x
...    x = property(getx, setx)
...
>>> a = Cal()
>>> a.x = 10
>>> a.x
10
property関数を活用すると、クラスやインスタンス中のプロパティを設定・取得するメソッド(アクセサ)の利用が自然になる。

次にデコレーターを使用したproperty関数の設定について、サンプルを示す。
def Property(func):
    return property(**func())
 
class Cal(object):
    def __init__(self):
        self.__x = None
 
    @Property
    def x():
        def fget(self):
            return self.__x
        def fset(self, value):
            self.__x = value
        return locals() 
property関数に設定する関数名はpropertyの引数キーワードと同じにする必要がある。

デコレーターを使用すると property関数の設定が簡単になる。しかしソース全体で見たときは簡単になっているかは疑問・・・。

ここでネットにあった別の設定方法を試す。
class Cal(object):
    def __init__(self):
        self.__x = None
 
    def x():
        def fget(self):
            return self.__x
        def fset(self, value):
            self.__x = value
        return locals() 
    x = property(**x())
ここでもproperty関数に設定する関数名はpropertyの引数キーワードと同じにする必要がある。

property関数にメソッドをキーワード引数として渡している。デコレーターを使った時より、簡単で理解しやすい。でもやっていることはデコレーターでの設定と同じ・・・。


この記事を書くのに参考にしたサイト
builder Pythonの技法:プロパティによるアクセサの実装
crazy()for(;;)you(); Pythonでプロパティ
Python ライブラリリファレンス
ActiveState Code Recipes