0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonのプロパティについて

Posted at

1. そもそもプロパティとは?

プロパティとは、「関数を、変数のように読み書きできる仕組み」です。

通常の関数呼び出し プロパティを使うと
john.get_age() john.age
john.set_age(30) john.age = 30

「関数を呼んでいる」ことを隠して、変数のように見せるのがプロパティの役割です。


2. property()を使う古い書き方

例)ageプロパティを作る

class MyClass:
    def __init__(self, name, age):
        self.name = name
        self._age = age  # 実データ

    def get_age(self):
        return self._age

    def set_age(self, value):
        self._age = value

    age = property(get_age, set_age)  # ここでまとめる
  • age = property(get_age, set_age)がポイント
  • john.ageget_age()が呼ばれる
  • john.age = 30set_age()が呼ばれる

3. @propertyを使う今風の書き方

例)ageプロパティを作る

class MyClass:
    def __init__(self, name, age):
        self.name = name
        self._age = age

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        self._age = value
  • getterには@propertyをつける
  • setterには@age.setterをつける
  • property()でまとめる必要がなく、すっきりシンプル

4. 関数名がプロパティ名になる理由

重要ポイント

@propertyでは、関数名=プロパティ名になります。

関数名 プロパティ名 アクセス方法
age age john.age
height height john.height
  • 関数名がageだからjohn.ageになる
  • 関数名がheightならjohn.heightになる

つまり

「プロパティ名=関数名」になるのが@propertyのルールです。


5. 無限ループが起きる原因

NG例)無限ループパターン

class MyClass:
    def __init__(self, name, age):
        self.name = name
        self._age = age

    @property
    def age(self):
        return self.age  # ここが間違い!

    @age.setter
    def age(self, value):
        self.age = value  # ここも間違い!
処理 説明
john.age getterが呼ばれる
getterの中でself.ageを見る またgetterが呼ばれる
またself.ageを見る 無限ループ!

setterでも同じことが起きる

@age.setter
def age(self, value):
    self.age = value  # setterを再帰的に呼んでしまう

6. 無限ループを防ぐ方法

プロパティではなく、直接本体(_age)を操作するのが正解です。

class MyClass:
    def __init__(self, name, age):
        self.name = name
        self._age = age  # 実データ

    @property
    def age(self):
        return self._age  # ←ここ重要!

    @age.setter
    def age(self, value):
        self._age = value  # ←ここも重要!
アクセス対象 説明
self.age getter/setterが呼ばれる
self._age ただのデータ(安全)

イメージまとめ

john.age = 30  # setterが呼ばれる
↓
self._age = 30  # 本体に直接アクセス
↓
john.age  # getterが呼ばれる
↓
return self._age  # 本体を返す

プロパティを自分で呼ばないから無限ループを回避!


7. まとめ

やりたいこと 正しい書き方 NGパターン
getter return self._age return self.age
setter self._age = value self.age = value
書き方 説明
property() getter・setterをまとめる古い方法
@property 今風のスマートな書き方

まとめの一言

getter・setterの中では、プロパティではなく直接データ(self._age)を触る
これが無限ループを防ぐ鉄則です!

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?