車輪の再開発ですが、Pythonにおいて継承できないメソッド・変数をまとめます。
継承できないメソッド・変数
結論からいうと、__(アンダースコアが2個)が冒頭についているメソッド・変数は継承できません。
次のスクリプトを見てみましょう。
class Parent: def __init__(self, v): self.v = v def func(self): print(self.v) def _func(self): print(self.v) def __func(self): print(self.v) class Child(Parent): def do(self): self.func() self._func() self.__func() child = Child(v=1) child.do()
このスクリプトは「'Child' object has no attribute '_Child__func'」というエラーが出力されて動きません。 Parentで定義した__funcメソッドにマングリング機構が働き、メソッド名が_Child__funcに変更してしまったためアクセスできなくなりました。
変数についても同じです。
class Parent: def __init__(self, v, _v, __v): self.v = v self._v = _v self.__v = __v def func(self): print(self.v) print(self._v) print(self.__v) class Child(Parent): def do(self): self.func() child = Child(v=1, _v=2, __v=3) child.do()
このときは、「__init__() got an unexpected keyword argument '__v'」というエラーを出力してしまいました。
使いどころ
__(アンダースコア2個)の変数は、継承できないことを利用して、名前衝突を防ぐことができます。一番分かりやすいのはコンストラクタ。
class Parent: def __init__(self, v): self.v = v class Child(Parent): def __init__(self, b): self.b = b
Parentの__init__にマングリング機構が働くことで、Childの__init__とは別のメソッドとなるのですね。(今まで、子クラスのコンストラクタで親クラスのコンストラクタをオーバライドしていると思っていましたが、勘違いでした)
まとめ
メソッド・変数ともに__(アンダースコア2個)が付いている場合は、継承できない。