Python PR

【Python】プロパティの定義と使い方を解説

記事内に商品プロモーションを含む場合があります

この記事では、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.xgettermc.x = 100setterdel mc.xdeleterが呼び出されています。

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デコレータ

gettersetterdeleterとして扱いたいメソッドに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()の引数を省略することで機能を制限できます。

クラスの定義:

以下のコードでは、setterdeleterを実装していないので読み出し専用のプロパティとなる。

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のプロパティの使い方を解説しました。

プロパティを使うことで扱いやすいクラスを実装することができました。インスタンス変数にアクセスする際に必ず何かしらの処理が必要ならプロパティを使いましょう!

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ