Python

Python初学者向け:プロパティについて基本から解説します

スポンサーリンク

 

この記事はこんな方におススメです
  • Pythonを始めたばかりで基本から学びたい方
  • Pythonの基本的な部分を速習してまずは全体像を把握しておきたい方

▶ クラスについて基本から学びたい方は以下の投稿をどうぞ

はじめに

本ブログでのクラスの学習もだいぶ進んできましたね。今回はプロパティについて基本から解説をしてきます。「プロパティとは」から説明を始めて、組み込み関数であるプロパティ関数によるgetter, setterの定義、「@property」デコレータや「@メソッド名.setter」デコレータによる設定まで解説をしていきます。

プロパティとは

プロパティは、値をしっかり管理したいけどインスタンス変数のように自然に値にアクセスしたい場合に使います。「クラスの外部からはインスタンス変数のように使用でき、クラス内部ではメソッドのように実装した属性のこと」です。

つまり、インスタンス変数にアクセスする際に、内部的にはメソッドを通した処理をしてくれる仕組みです。普通に値を取ってきているように見せて、裏ではメソッドを動かす、普通に値をセットしているように見せて、裏ではメソッドを動かす、ということですね。このようにすることで、たとえば値をセットするときであれば、メソッド内にvalidationチェックを入れる、ということもできますね。

プロパティには、値を取得するためのgetter(ゲッター)、値をセットするためのsetter(セッター)、値を削除するためのdeleter(デリーター)があります。

プロパティを実装する

プロパティを設定するには組み込み関数のproperty関数を使う方法と、デコレータを使う方法((「@property」デコレータや「@メソッド名.setter」デコレータ)など)があります。順にみていきましょう。

property()を使う

最初に書式を確認しておきましょう。次のような書式で定義することができます。

属性値 = property(fget, fset, fdel, doc)

fgetにはプロパティの値を読みだすためのメソッド、fsetにはプロパティの値を設定するためのメソッド、fdelにはプロパティの値を削除するためのメソッド、docにはプロパティのヘルプ文字列(docstring)を指定します。

__init__内で定義するインスタンス変数は「_(アンダースコア)」を付けた変数名とする必要があるので、注意が必要です。

実際にこの動きをgetter, setter で確認しましょう。

class Animal():
    def __init__(self,name):
        self._name = name
        
    def get_name(self):
        print('getterでデータを取得しています')
        return self._name
    
    def set_name(self,new_name):
        print('setterでデータを書き換えています')
        self._name=new_name
    
    name = property(get_name,set_name)

Animalクラスを作成しました。今回はインスタンス変数はnameのみです。ここでは、このnameにgetter, setterを設定したいので、アンダースコアを付けた変数名「_name」とします。(3行目)

5-7行目でgetterメソッドを定義しています。このメソッドが呼ばれたことが確認できるように6行目にprint文を入れています。このメソッドは「_name」属性を読みだすだけのメソッドです。

9-11行目でsetterメソッドを定義しています。このメソッドも呼ばれたことが確認できるように10行目にprint文を入れています。このメソッドは引数「new_name」をとり、「_name」の値を書き換えます。

13行目でproperty関数を使って、get_nameメソッドをgetter(第一引数fget)、set_nameメソッドをsetter(第二引数fset)の設定をしています。

では、インスタンスを一つ作って、インスタンス変数の値を見てみることにしましょう。

# インスタンスの作成
rakuda=Animal('rakuda')

# nameを取得
rakuda.name
getterの確認

まずrakudaというインスタンスを作成して、その後、このインスタンスの属性nameを取得しています。すると、「getterでデータを取得しています」が表示されて、その後に「rakuda」という値が表示されています。値の取得に「get_name」メソッドが使われていることがわかりますね。

同様にsetterについても見てみましょう。

# nameの書き換え
rakuda.name='らくだ'
setterの確認

普通にname属性を読んで書き換えているように見えますが、結果を見ると「setterでデータを書き換えています」と表示されているので、「set_name」メソッドが呼ばれたことがわかりますね。念のため、値が書き換わっているのかを確認してみましょう。

# nameの確認
rakuda.name
nameが書き換わっていることの確認

getterが呼ばれて、その後に「らくだ」が返ってきました。値がちゃんと書き換わっていますね。

外からはインスタンス変数「name」にアクセスすると、裏側ではメソッドを使って読み書きする仕組みになっています。クラス内部では「_name」のように「_(アンダースコア)」を付けた変数名とすることに注意しましょう。

デコレータを使う

同じことがデコレータを使って書くこともできます。getterには「@propery」デコレータで修飾します。setterはgetterと同じ名前のメソッドとして、「@メソッド名.setter」というデコレータで修飾します。

class Animal():
    def __init__(self,name):
        self._name = name
        
    @property    
    def name(self):
        print('getterでデータを取得しています')
        return self._name
    
    @name.setter
    def name(self,new_name):
        print('setterでデータを書き換えています')
        self._name=new_name

今回はgetter, setterのメソッド名は「name」としています。getterには「@propery」デコレータ、setterには「@name.setter」デコレータで修飾しています。

先ほどと同じように試してみましょう。まず、name属性の確認です。

# インスタンスの作成
rakuda=Animal('rakuda')

# nameを取得
rakuda.name
デコレータを用いた場合のgetterの確認

先ほどと同じように普通にname属性にアクセスすると、裏側でメソッドが走っているのがわかりますね。同様にsetterについても確認しておきましょう。

# nameの書き換え
rakuda.name='らくだ'
デコレータを用いた場合のsetterの確認

setterが動いていることが確認できました。念のため値を見ておきましょう。

# nameの確認
rakuda.name
デコレータを用いた場合の書き換えの確認

再び、getterが呼ばれて値を取ってきています。「らくだ」に書き換わっていることが確認できました。

スポンサーリンク

まとめ

今回はプロパティについて扱いました。プロパティは外からインスタンス変数に不通にアクセスすると、裏側ではメソッドが呼ばれて値を返したり、書き換えたりする仕組みを構築するための仕組みです。その設定方法には2種類あり、一つは組み込み関数であるproperty関数を使う方法、もう一つはデコレータを使う方法です。

クラス内ではアンダースコアを付けた名称のインスタンス変数(今回の例では「_name」)とすることに注意するようにしてください。

またデコレータを使って設定する場合は、getter, setterのメソッド名は同じ名前にする、ということも忘れないようにしましょう。

コメント

タイトルとURLをコピーしました