Pythonの技法:プロパティによるアクセサの実装

文:Nick Gibson(Builder AU)  翻訳校正:原井彰弘
2008-01-07 18:00:00
  • このエントリーをはてなブックマークに追加

 プロパティは関数の属性値の設定、取得、削除を定義する一つの方法である。プロパティが提供するメソッドを用いると、フィールドへのアクセス方法を定義して、フィールドの標準的なインタフェースを使用することが可能になる。

 先ほどのクラスを別の方法で実装してみよう。

class C(object):
y = 3
z = 4

def __init__(self):
self.__x = 2

def getx(self):
return self.__x

def setx(self, val):
print "x is read only"

x = property(getx, setx)

 このクラスでは変数xをプロパティとし、getx関数とsetx関数を用いてアクセスできるようにしている(オプションの第3引数を指定すると、値の削除が可能になる。また、第4引数ではdocstringを指定できる。しかし、それらは今のところ気にしなくてよいだろう)。

 このようにして定義されたCクラスでは、より自然な方法でフィールドを使用できる。

>>> i = C()
>>> i.x, i.y, i.z
(2, 3, 4)
>>> i.x = 5
x is read only
>>> dir(i)
['_C__x', '__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__', '__weakref__', 'getx', 'setx', 'x', 'y', 'z']
>>> i._C__x = 5
>>> i.x, i.y, i.z
(5, 3, 4)

 ただし、プロパティを用いても、内部をよく調べればまだ変数に直接アクセスすることが可能だ。

 プロパティを用いずに同様の機能を実現する手法としては、属性を設定する際にデフォルトで用いられるメソッドをオーバーライドしてしまう方法がある。この手法を用いた場合、コードは次のようになる。

class D(object):
    x = 2
    y = 3
    z = 4

    def __setattr__(self, name, val):
        if name != 'x':
            self.__dict__[name] = val
        else:
            print "%s is read only" % (name)

 使い方はほとんど同じだ。

>>> i = D()
>>> i.x, i.y, i.z
(2, 3, 4)
>>> i.x = 5
x is read only
>>> dir(i)
['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__',
'__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__setattr__', '__str__', '__weakref__', 'x', 'y', 'z']
>>> i.__dict__['x'] = 5
>>> i.x, i.y, i.z
(5, 3, 4)

 Pythonの哲学である「There’s only one way to do it」(それを実行する方法は一通りしかない)からは逸脱することになるかもしれないが、どの手法を用いるかはあなた自身が決めることである。本稿で挙げたような小規模な例では、プロパティを用いるとgetterやsetterをそれぞれのフィールドに記述する必要が生じ、コード量が増加してしまう。しかし、それぞれに異なった動作をさせたい場合は、__setattr__関数にすべてを詰め込もうとすると、ずっと読みにくく保守しにくいコードになってしまうだろう。

この記事は海外CNET Networks発のニュースをシーネットネットワークスジャパン編集部が日本向けに編集したものです。海外CNET Networksの記事へ

このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]