他のオブジェクト指向プログラム言語、特に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つの手でですね。