0
2

More than 3 years have passed since last update.

pythonの@propertyについて

Last updated at Posted at 2020-07-29

@propertyについて語るには、基礎から語らなきゃいけないんです。

学校の例を見てみましょう。学生というクラスがあるとしましょう。

通常、クラスの属性を決めるときに、属性をそのまま公開しても良いのですが、勝手に変更することが可能となり、あまりおすすめできません。というのも、点数は通常0 ~ 100の範囲内に位置するので、デタラメに9999にもできてしまいます。明らかにおかしいですね。

s = Student() #オブジェクト作成
s.score = 9999
s.score = 1111
# 勝手に書き換えられる

ということで、set_score()get_score()で成績を取得することにしました。(普通の流れです)

class Student:
  def get_score():
    return self.self._score

  def set_score(self, value):
    if not isinstance(value, int):
      raise ValueError("score must be an integer! ")
    if value < 0 or value > 100:
      raise ValueError("score must be between 0 ~ 100!")
    self._score = value

これでもう勝手に属性を書き換えられなくなったんだね。点数は0 ~ 100の範囲じゃなきゃだめだとと制限をかけることができました。

>>> s = Student()
>>> s.set_score(60) # ok!
>>> s.get_score()
60
>>> s.set_score(9999)
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100!

しかし、これは少し複雑さを増したようなきがするんだ。なんかここでズルをしたくなって、get, setみたいな複雑な方法ではなく、普通に属性を呼びたい、また、勝手に書き換えもできないような方法はないの???って知りたくなった。
あるよ。それは@property

class Student:
  @property
  def score(self):
    return self._score

  @score.setter
  def score(self, value):
    if not isinstance(value, int):
     raise ValueError("score must be an integer!")
    if value < 0 or value > 100:
      raise ValueError("score must be between 0 ~ 100!")
    self._score = value

@propertyは少し複雑なので、中身の説明は割愛します。まずは使えるようにしよう。getterの方法を属性にしたいときに、@propertyを足せばいい。@propertyがもう一個のデコレーター@score.setterを作成した。これを持ってsetter方法を属性のようにします。
getter -> @property
setter -> 属性.setter

>>> s = Student()
>>> s.score = 60 # OK 実際はre(60)
>>> s.score # OK 実際はs.get_score()
60
>>> s.score = 9999
Traceback (most recent call last):
  ...
ValueError: score must between 0 ~ 100! 
# 自分で定義したエラーメッセージ

read onlyの属性を定義することも可能→getterメソッドだけ定義し、setterメソッドを定義しなければread onlyですよ。

class Student(object):

    @property
    def birth(self):
        return self._birth

    @birth.setter
    def birth(self, value):
        self._birth = value

    @property
    def age(self):
        return 2014 - self._birth
# birthは書き換えも読み込みもできるが、ageは読み込みのみできる。

さいごに

@propertyはクラスの定義においてよく使われているので、使えるようにしましょう。私も実はブロックチェーンの練習で@propertyに出会って思い出すために、ここでメモっておきました。

さてさてまたね。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2