Pythonを真面目にゆっくり学ぶべく
を参考に学んでいきます*1。
前回
6. オブジェクトとクラス
6.3 継承
コーディング上の問題解決において、既存のクラスで必要なことを殆どしてくれるオブジェクトが作成できる際に便利なのが継承である。すなわち使いたい既存のクラスを指定し、追加ないし変更したい一部のみを定義した新しいクラスを作る。これによりメンテナンスしなければならないコードを省略できる。
こうして継承した新たなクラスでは、古いクラスの動作は使われない(オーバーライド)。
6.3.2 selfの自己弁護
インスタンスメソッド(これまでの例で作成したメソッド)の第一引数としてを組み込まなければならないことは度々の欠点として批判されることがある。はこの引数を用いて適切なオブジェクトの属性とメソッドを見つけてくる。
class Car(): def exclaim(self): print("I'm a car!") car = Car() car.exclaim()
上記の例においては
- オブジェクトのクラス()を探し出す。
- クラスのメソッドに引数としてオブジェクトを渡す。
という動作を行う。
6.4 プロパティによる属性値の取得、設定
オブジェクト指向言語の中には、クラスの中に外部から直接アクセスできない非公開なオブジェクト属性をサポートしている場合がある。は基本的にすべての属性とメソッドは公開であるものとして書くことが前提となっている。ただしプロパティを設定することでに相当するものを設定することはできる。
プロパティはデコレーターで定義することもできる。
ゲッターメソッドの前に付けるデコレーター | |
セッターメソッドの前に付けるデコレーター |
######################## ### プロパティの設定 ### ######################## # hidden_nameを非公開にしたい属性とする class Duck(): def __init__(self, input_name): self.hidden_name = input_name def get_name(self): print('inside the getter') return self.hidden_name def set_name(self, input_name): print('inside the setter') self.hidden_name = input_name name = property(get_name, set_name) # fowl = Duck('Howard') fowl.name fowl.get_name() fowl.name = 'Daffy' fowl.name ########################################## ### デコレーターによるプロパティの設定 ### ########################################## class Duck(): def __init__(self, input_name): self.hidden_name = input_name @property def name(self): print('inside the getter') return self.hidden_name @name.setter def name(self, input_name): print('inside the setter') self.hidden_name = input_name # fowl = Duck('Howard') fowl.name fowl.name = 'Donald' fowl.name
プロパティには、属性の直接アクセスよりもメリットがある。プロパティの定義を書き換えても、クラス定義内のコードを書き換えるのみで済み、呼び出し元には手を付ける必要がないことである。
########################################## ### デコレーターによるプロパティの設定 ### ########################################## class Circle(): def __init__(self, radius): self.radius = radius @property def diameter(self): return 2 * self.radius # c = Circle(5) c.radius c.diameter # 属性は自由に書き換えられる c.radius = 7 c.diameter # セッターを指定しなければ外部からプロパティを設定できない c.diameter = 20
6.5 非公開属性のための名前のマングリング
クラス定義の外からは見えないようにするクラス属性には__(アンダースコア2つ)を名前の先頭に付ける。
この命名方法を用いると、偶然にプロパティをアクセスしないようにはマングリングをする。
#################### ### マングリング ### #################### class Duck(): def __init__(self, input_name): self.__name = input_name @property def name(self): print('inside the getter') return self.__name @name.setter def name(self, input_name): print('inside the setter') self.__name = input_name # fowl = Duck('Howard') fowl.name fowl.name = 'Donald' fowl.name fowl.__name
*1:第2版が出ているものの初版しか持っていないのでこちらで。