他のオブジェクト指向プログラム言語、特にJavaようにカプセル化を是とする言語をメインで経験された方は、クラスのメンバにアクセスするためのgetter、setterメソッドを実装してしまいがちですが、pythonではどのように実装するのが望ましいのでしょうか。
getter/setter
冒頭で書いたとおり、Javaを経験された方はクラスに以下のようなコードを書いてしまうのではないでしょうか?(実際、私がそうでした。)
class User:
def __init__(self, name):
self.name = name
self.age = None
def get_name(self):
return self.name
def set_name(self, name):
self.name = name
def get_age(self):
return self.age
def set_age(self, age):
self.age = age
ですが、pythonではこのような書き方はあまりしません。というのも、そもそも厳密な意味でのメンバの隠蔽が言語仕様としてできないためあまり意味がありません。pythonでは公開されたメンバに対して直接アクセスします。
class User:
def __init__(self, name):
self.name = name
self.age = None
if __name__ == '__main__':
user = User('kuro')
# 利用側はドットで直接アクセスします。
user.age = 19
print(user.name + "さんは" + str(user.age) + "歳です")
また、メンバアクセス時に何らかの処理を加えたい場合は、プロパティを活用しましょう。これによりアクセスを制限したり、不正な値を排除することが可能となります。(プロパティについてはこちらをご参照ください。)
例えば、上のサンプルでageに値を設定ときに0以上の整数を使わせたい場合、以下のように記述します。
class User:
def __init__(self, name):
self.name = name
self.__age = None
@property
def age(self):
return self.__age
@age.setter
def age(self, age):
if type(age) == int:
if age > 0:
self.__age = age
return
raise ValuError('年齢は0以上の整数を指定してください')
変更させたくない場合は、問答無用でsetter内で例外を起こすのも1つの手でですね。
