概要
Python の super(PClass, obj)
の挙動がよくわからなかったので確認しました
結論から言うと
- obj で指定した親クラス内で PClass の次の親クラスのメソッドをコールする
が正しい挙動っぽいです
環境
- macOS 11.7.10
- Python 3.11.6
とりあえず単純な親クラスの挙動を確認
継承一段階の挙動の確認です
class A:
def say(self):
print("A") # => A
class B(A):
def say(self):
super().say() # => A
print("B") # => B
if __name__ == "__main__":
a = A()
a.say()
b = B()
b.say()
もう少し継承する
継承を3段階まで伸ばしてみます
継承の歴史が長い D の場合 A,B,C すべての親クラスの say がコールされているが確認できます
class A:
def say(self):
print("A") # => A
class B(A):
def say(self):
print("super from B")
super().say() # => A
print("B") # => B
class C(B):
def say(self):
print("super from C")
super().say() # => A,B
print("C") # => C
class D(C):
def say(self):
print("super from D")
super().say() # => A,B,C
print("D") # => D
if __name__ == "__main__":
a = A()
a.say()
b = B()
b.say()
c = C()
c.say()
d = D()
d.say()
歴史の順番で親クラスをコールしないための super(class, obj)
先程の D で B, C の say をコールしたくない場合があります
そんな場合に super(class, obj) を使う感じです
要するに途中にある親クラスのメソッドをすっ飛ばすことができます
class A:
def say(self):
print("A") # => A
class B(A):
def say(self):
print("super from B")
super().say() # => A
print("B") # => B
class C(B):
def say(self):
print("super from C")
super().say() # => A,B
print("C") # => C
class D(C):
def say(self):
print("super from D")
super(B, self).say() # => A
print("D") # => D
if __name__ == "__main__":
a = A()
a.say()
b = B()
b.say()
c = C()
c.say()
d = D()
d.say()
最後に
Python の super の挙動を確認してみました
super(class, obj) と途中の親クラスのメソッドをすっ飛ばすことができる呼び出し方だと覚えておけばいいかなと思います
歴史は結局たどるので最後の D の部分は
super(C, self).say()
とすると A,B と表示されるので注意しましょう
self の親クラスの歴史の C の次の B だけがコールされるわけでないので注意が必要です
0 件のコメント:
コメントを投稿