Pythonのsuperについて

Pythonのsuperクラスについてpyhack Slackでatsuoishimotoに教えて貰いました。

superは第2引数を省略することができます。何に使うのでしょうか?

>>> class A: pass
...
>>> super(A)
<super: <class 'A'>, NULL>

これは unbound super と言います。使い方は

class A(object):
    def method(self):
        print('A')

class B(A):
    def method(self):
        print('B')
        self.__super.method()

B._B__super = super(B)

B().method()

のように使うみたいですがどんなシーンで使うのかまったく想像できません。
B._B__super = super(B) はBクラスのprivateインスタンスメンバに代入しているので超絶hackしてますね。。。

super(B).__get__(B()).method()

ならわかりやすいですね。

ではsuper(A, B)は何に使うのでしょうか?

class A:
    @classmethod
    def f(cls):
        print('A')

class B(A):
    @classmethod
    def f(cls):
        super(B, cls).f()

単純に classmethod の場合に使うようですね。
ということはsuperクラスのデスクリプタはどうなっているんでしょうか?

>>> class B(A): pass
...
>>> super(B).__init__
<method-wrapper '__init__' of super object at 0x7fc8c12e3b08>
>>> super(B, B()).__init__
<method-wrapper '__init__' of B object at 0x7fc8c13953c8>

unbound superのget()は普通のsuper()のインスタンスを返します。
bounded superは引数を無視します。

>>> super(B, B()).__get__(123).__init__
<method-wrapper '__init__' of B object at 0x7fc8c12defd0>

Python考古学ですね。

Thanks atsuoishimoto!!

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください