初心者データサイエンティストの備忘録

調べたことは全部ここに書いて自分の辞書を作る

継承できないメソッド・変数

車輪の再開発ですが、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個)が付いている場合は、継承できない。