はじめに
Twitterで一時期流行していた 100 Days Of Code なるものを先日知りました。本記事は、初学者である私が100日の学習を通してどの程度成長できるか記録を残すこと、アウトプットすることを目的とします。誤っている点、読みにくい点多々あると思います。ご指摘いただけると幸いです!
今回学習する教材
-
- 8章構成
- 本章216ページ
今日の進捗
- 進行状況:87-91ページ
- 第4章:メタクラスと属性
- 本日学んだことの中で、よく忘れるところ、知らなかったところを書いていきます。
getやsetメソッドよりも素のままの属性を使う
getやsetメソッドを定義すると、計算をするときにぎこちないコードになってしまいます。
class OldResistor(object):
def __init__(self, ohms):
self._ohms = ohms
def get_ohms(self):
return self._ohms
def set_ohms(self, ohms):
self._ohms = ohms
r0 = OldResistor(100)
r0.set_ohms(r0.get_ohms() + 500)
print(r0.get_ohms())
# 600
それよりも素の属性を使ったほうが計算時にすっきりしたコードになります。
class Resistor(object):
def __init__(self, ohms):
self.ohms = ohms
self.voltage = 0
self.current = 0
r1 = Resistor(50e3)
r1.ohms = 400
r1.ohms += 200
print(r1.ohms)
# 600
後に、属性が設定された時に特別な振る舞いが必要になる場合は、@propertyデコレータとそれに対応する、setter属性を付与すれば良いです。
また、正しく動作するためには、セッターメソッドとゲッターメソッドの両方の名前が、意図しているプロパティ名と一致しないとダメです。
class VoltageResistance(Resistor):
def __init__(self, ohms): # 初期化
super().__init__(ohms) # ohmsを引数として、親クラスの__init__を呼び出す
self._voltage = 0 # インスタンス変数 _voltageを宣言
@property # _voltageに入っている値を返す
def voltage(self):
return self._voltage
@voltage.setter # voltageに新たな値を代入するたびにセッターメソッドが実行される
def voltage(self, voltage): # プロパティ名と一致
self._voltage = voltage
self.current = self._voltage / self.ohms
r2 = VoltageResistance(100)
print(r2.current)
# 0
r2.voltage = 10 # voltage.setterが呼ばれ、voltageに10を渡す
print(r2.current)
# 0.1
このように、素の属性を使い、@propertyを使うことですっきりしたコードを書きながら機能を拡張することができます。@propertyメソッドを使ってセッターやゲッターを実装する際に、可読性を落とさないために以下のポイントを抑えるべしです。
関連するオブジェクト状態だけを変更し、オブジェクトを超えて、モジュールを動的にインポートする、遅いヘルパー庵数を実行するなどの、呼び出し元が予期しない動作をしないように注意!
また、複雑であったり遅くなるような場合は通常のメソッドを使って実装すべきなようです。