かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Python3 class の getter / setter のメモ

また Python を少し触っています。

private 変数 のおさらい

__ 始まりで作成された変数はインスタンスからしかアクセスできない private 変数になる

class User(object):
  def __init__(self, name):
    self.__name = name
  
  def hi(self):
    print(f'Hi, {self.__name}')

ichigo = User('Ichigo')
ichigo.hi()
# => Hi, Ichigo

# private 変数にアクセスしようとしたらエラー
ichigo.__name
# => AttributeError: 'Idol' object has no attribute '__name'

# 存在しない変数にアクセスしようとしてもエラー
ichigo.name
# => AttributeError: 'Idol' object has no attribute 'name'

# private 変数に値を代入
# エラーにはならないが無視される (更新されない)
ichigo.__name = 'Aoi'

ichigo.hi()
# => Hi, Ichigo

インスタンスからしかアクセスできないのチョット使い勝手が悪いので、他の言語にもあるような getter / setter を作成したい。

1. @property デコレーターを使う方法

  • getter: @property デコレーターを使ってメソッドを定義する
  • setter: @{property_name}.setter デコレーターを使ってメソッドを定義する
class User(object):
  def __init__(self, name):
    self.__name = name
  
  def hi(self):
    print(f'Hi, {self.__name}')
  
  # name という getter / setter を作成する
  @property
  def name(self):
    return self.__name

  @name.setter
  def name(self, name):
    self.__name = name

api = User('Aoi')
print(aoi.name)  # => 'Aoi'
aoi.name = 'Kiriya'
print(aoi.name)  # => 'Kiriya'
api.hi() # => Hi, Kiriya

2. property(getter_method, setter_method) 関数を使う方法

property_name = property(getter_method, setter_method) で getter / setter を作成できる

class User(object):
  def __init__(self, name):
    self.__name = name

  def hi(self):
    print(f'Hi, {self.__name}')

  def get_name(self):
    return self.__name

  def set_name(self, name):
    self.__name = name

  # getter で get_name, setter で set_name を呼び出す
  name = property(get_name, set_name)

ran = User('Ran')
print(ran.name)  # => 'Ran'
ran.name = 'Shibuki'
print(ran.name)  # => 'Shibuki'
ran.hi()  # => 'Hi, Shibuki'

₍ ᐢ. ̫ .ᐢ ₎ デキタ!


[参考]