この記事では、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'
プロパティを実装することでもっとシンプルに扱えるようになります。
プロパティの実装
プロパティを実装するには、「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は省略不可)
class MyClass:
def __init__(self, x):
self._x = x
# getter
@property
def x(self):
print('get_x')
return self._x
まとめ
この記事では、Pythonのプロパティの使い方を解説しました。
プロパティを使うことで扱いやすいクラスを実装することができました。インスタンス変数にアクセスする際になにか処理がしたいならプロパティを使いましょう❗️
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ