この記事では、Pythonのプロパティ定義と使い方を解説します。
プロパティとは、「クラスに定義されているインスタンス変数を取得・変更・削除するときに何かしらの処理を加えるための機能」です。 例えば、値を取得する際に四捨五入したり、代入する際に型をチェックしたりできます。
プロパティを実装することで安全で誰でも使いやすいクラスを実装することができます。
それでは、プロパティの使い方を見ていきましょう!
プロパティとは?
プロパティとは、クラス外部からはインスタンス変数のように使用でき、クラス内部ではメソッドのように実装した属性のことです。
つまり、インスタンス変数にアクセスする際にメソッドを通したい(何かしらの処理を加えたい)場合に使用します。
プロパティには、値を取得するためのgetter(ゲッター)、値をセットするためのsetter(セッター)、値を削除するためのdeleter(デリーター)があります。
これらプロパティは通常のメソッドを使って実装することもできます。メソッドを使って実装してみると以下のような感じになります。
クラスの定義:
class MyClass: def __init__(self, x): self._x = x # getter def get_x(self): print('get_x') return self._x # setter def set_x(self, x): print('set_x') self._x = x # deleter def del_x(self): print('del_x') del self._x
インスタンス化・アクセス:
mc = MyClass(1) print(mc.get_x()) # get_x # 1 mc.set_x(100) # set_x print(mc.get_x()) # get_x # 100 mc.del_x() # del_x print(mc.get_x()) # get_x # AttributeError: 'MyClass' object has no attribute '_x'
しかし、メソッドでプロパティを実装するとインスタンス変数にアクセスするためにいちいちメソッドを呼び出さなければならないので分かりづらく不便です。
Pythonではプロパティを実装するための関数やデコレーターが用意されています。それらの機能を使うことでもっと簡単に使いやすいプロパティを実装することができます。
プロパティの実装
それではプロパティを実装していきますが、Pythonでプロパティを実装するには、「property()関数を使う方法」と「propertyデコレータを使う方法」があります。
どちらを使用しても問題ありませんが、個人的にはpropertyデコレータの方がオススメです。
property()関数を使う
propertyクラスのコンストラクタは、以下の引数をとります。
property(fget=None, fset=None, fdel=None, doc=None)
| fget | getterとして使用するメソッドを渡す |
|---|---|
| fset | setterとして使用するメソッドを渡す |
| fdel | deleterとして使用するメソッドを渡す |
| doc | docstring(簡単にプロパティの説明を書いておく) |
例として、先ほどのコードをproperty()を使って書き直すと以下のようになります :
クラスの定義:
class MyClass: def __init__(self, x): self._x = x # getter def get_x(self): print('get_x') return self._x # setter def set_x(self, x): print('set_x') self._x = x # deleter def del_x(self): print('del_x') del self._x x = property(get_x, set_x, del_x, 'x property.')
インスタンス化・アクセス:
mc = MyClass(1) print(mc.x) # get_x # 1 mc.x = 100 # set_x print(mc.x) # get_x # 100 del mc.x # del_x print(mc.x) # get_x # AttributeError: 'MyClass' object has no attribute '_x'
mc.xでgetter、mc.x = 100でsetter、del mc.xでdeleterが呼び出されています。
property()で生成したインスタンスの名前がプロパティ名となります。以下のようにインスタンス名をyにしたらmc.yでアクセスします。
class MyClass: # 省略... # インスタンス名をyに変更 y = property(get_x, set_x, del_x, 'x property.') mc = MyClass(1) print(mc.y) # get_x # 1
propertyデコレータ
getter、setter、deleterとして扱いたいメソッドにpropertyデコレータを付与することでプロパティを実装できます。
例として、先ほどのコードをpropertyデコレータを使って書き直すと以下のようになります :
class MyClass: def __init__(self, x): self._x = x # getter @property def x(self): '''x property''' print('get_x') return self._x # setter @x.setter def x(self, x): print('set_x') self._x = x # deleter @x.deleter def x(self): print('del_x') del self._x
- @propertyデコレータは、付与されたメソッドの名前(ここではx)をそのまま使って、読み出し専用属性のgetterとする
- setterには「@getter名.setter」、deleterには「@getter名.deleter」を付与します
- setterとdeleterのメソッド名は、getterと同じ名前にする
プロパティの機能を制限する
それぞれのプロパティの実装を省略することで機能を制限することができます。例えば、getterのみを実装することで読み出し専用のプロパティとして定義できます。
property()
property()の引数を省略することで機能を制限できます。
クラスの定義:
以下のコードでは、setterとdeleterを実装していないので読み出し専用のプロパティとなる。
class MyClass: def __init__(self, x): self._x = x # getter def get_x(self): print('get_x') return self._x x = property(get_x)
インスタンス化・アクセス:
mc = MyClass(1) print(mc.x) # get_x # 1 mc.x = 100 # AttributeError: can't set attribute
setterは実装していないので値をセットしようとするとエラーが発生しました。
propertyデコレータ
特定のデコレータを付与しなければ機能を制限できます。(ただし、getterは省略不可) 以下のコードでは、getterのみを実装しました。
class MyClass: def __init__(self, x): self._x = x # getter @property def x(self): print('get_x') return self._x
このように機能を制限することでより安全なプロパティを実装することができました。
まとめ
この記事では、Pythonのプロパティの使い方を解説しました。
プロパティを使うことで扱いやすいクラスを実装することができました。インスタンス変数にアクセスする際に必ず何かしらの処理が必要ならプロパティを使いましょう!
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ
- property - 組み込み関数 — Python 3.9.4 ドキュメント


