[Python] 14. クラスプロパティ(Property)


Study / Python    作成日付 : 2020/06/12 17:45:13   修正日付 : 2020/06/12 17:45:13

こんにちは。明月です。


この投稿はPythonのクラスプロパティ(Property)に関する説明です。


まず、クラスのプロパティはクラス内部変数を参照するような関数の意味です。 普通はゲッター(getter)、セッター(setter)という時もあります。

クラスを生成する時に内部メンバー変数をpublicタイプで生成することはできますが、OOPのカプセルの特性でクラスの内部メンバー変数を直接に参照することはよくないです。(Pythonは別にOOPプログラム言語ではないですが。。。)

なぜなら、クラスを生成する理由はオブジェクトの意味を合わせて作った変数がクラスですが、直接に変数を参照することになるとクラスの意味がなくなることです。

# 成績を管理するクラス
class People():
  # コンストラクタ (名前、日本語、数学、英語)	
  def __init__(self, name, japanese, math, english):
    # メンバー変数設定
    self.name = name
    self.japanese = japanese
    self.math = math
    self.english = english
  # 成績計算
  def calc(self):
    # 総点を計算
    self.total = self.japanese + self.math + self.english
    # 平均点数を計算
    self.avg = self.total / 3
  # 出力
  def print(self):
    # 名前をコンソール出力
    print("name - " + self.name)
    # 総点をコンソール出力
    print("total - " + str(self.total))
    # 平均点数をコンソール出力
    print("avg - " + str(self.avg))
# インスタンスを生成
a = People("test", 70, 80, 90)
# 点数を計算
a.calc()
# コンソール出力
a.print()
# 改行
print()
# 平均点数を修正
a.avg = 100
# コンソール出力
a.print()


上の例をみればPeopleクラスに国語、数学、英語をいれてcalc関数で総点と平均点数を計算します。

でもpublicになるとa.avgで平均点数値を修正ができます。上みたいにクラスを設計すればクラスの意味がなくなります。なので変数のアクセスを制御する必要がありますが、それがクラスプロパティです。

# クラス生成
class Main():
  # コンストラクタ
  def __init__(self):
    # publicのメンバー変数
    self.data1 = "good"
    # 変数名の前でアンダーバー(_)が二つあればprivate設定、つまり外部でアクセスができない。
    self.__data2 = "morning"
# インスタンスを生成
a = Main()
# data1はpublicタイプでアクセスができる。
print(a.data1)
# data2はprivateタイプでアクセスができない。
print(a.__data2)


でも、クラスのメンバー変数を参照しなければならない時があります。その時にはpublicにすることではなく、ゲッター、セッターのプロパティを設定して参照します。

# クラス生成
class Main():
  # コンストラクタ
  def __init__(self):
    # メンバー変数設定
    self.__data = ""
  # data変数の値をクラス外部で参照するようなゲッター
  def get_data(self):
    return self.__data
  # data変数の値をクラス外部で設定するようなセッター
  def set_data(self, data):
    self.__data = data
# インスタンスを生成
a = Main()
# aクラスの__dataを設定
a.set_data("good")
# aクラスの__dataを出力
print(a.get_data())


実は上みたいにゲッター、セッター関数で変数を参照してもpythonの標準コーディングに間違いことではないです。Javaの場合はプロパティを上みたいにゲッター、セッター関数で参照します。

C#の場合はプロパティ文法が別にあります。


pythonもデコレートを使ってプロパティを設定することができます。

# クラス生成
class Main():
  # コンストラクタ
  def __init__(self):
    # メンバー変数設定
    self.__data = ""
  # ゲッター設定
  @property
  def data(self):
    # メンバー変数を返却
    return self.__data
  # セッター設定、 ゲッター名.setter
  @data.setter
  def data(self,data):
    # メンバー変数を設定
    self.__data = data
# インスタンスを生成
a = Main()
# セッター関数でデータを設定
a.data = "good"
# ゲッター関数でデータを受け取る。
print(a.data)
# セッター関数でデータを設定
a.data = "hello"
# ゲッター関数でデータを受け取る。
print(a.data)


Pythonのクラスプロパティはセッターだけを生成ができません。@ゲッター名.setterなのでゲッターが無ければセッター設定ができないです。

# クラス生成
class Main():
  # コンストラクタ
  def __init__(self):
    # メンバー変数設定
    self.__data = ""
  # セッター設定、 ゲッター名.setter
  @data.setter
  def data(self,data):
    # メンバー変数を設定
    self.__data = data
# インスタンスを生成
a = Main()
# セッター関数でデータを設定
a.data = "hello"


でも、ゲッターだけには設定ができます。ゲッターだけあれば読み取り専用変数になります。

# クラス生成
class Main():
  # コンストラクタ
  def __init__(self):
    # メンバー変数設定
    self.__data = 0
  # ゲッター設定
  @property
  def data(self):
    # 呼び出すたびにdataが1ずつに増加するカウントを作成した。
    self.__data = self.__data + 1
    # 返却
    return self.__data
# インスタンスを生成
a = Main()
# ゲッターでデータを取得、カウントがあるから呼び出すたびに1ずつ増加する。
print(a.data)
# ゲッターでデータを取得
print(a.data)
# ゲッターでデータを取得
print(a.data)
# ゲッターでデータを取得
print(a.data)
# ゲッターでデータを取得 	
# セッターはないのでエラーが発生する。
a.data = 10


セッターを設定してないので産所するとエラーが発生します。


ここまでPythonのクラスプロパティ(Property)に関する説明でした。


ご不明なところや間違いところがあればコメントしてください。

最新投稿