[解決済み] super().method() と super(self.__class__,self).method() の違いについて [重複]。
質問
以下は、私が書こうとしていたコードです。
class A(object):
def bind_foo(self):
old_foo = self.foo
def new_foo():
old_foo()
#super().foo()
super(self.__class__,self).foo()
self.foo = new_foo
def __init__(self):
print("A __init__")
def foo(self):
print("A foo")
class B(A):
def __init__(self):
print("B __init__")
super().__init__()
def foo(self):
print("B foo")
super().foo()
class C(A):
def __init__(self):
print("C __init__")
super().__init__()
super().bind_foo()
def foo(self):
print("C foo")
b = B()
b.foo()
c = C()
c.foo()
BクラスとAクラスは期待される動作、つまり、私が呼び出したときに
b.foo()
を呼び出す。
a.foo()
と同様に
super()
. クラスCは、子Bと親Aの動作を模倣しようとしていますが、今回は、明示的に
super().foo()
は子クラスで、親クラスの
foo()
が呼び出されます。期待通りに動作しています。
しかし、私がよく理解していないのは、以下のように
A.bind_foo
を使用する必要があります。
super(self.__class__,self).foo()
よりも
super().foo
.
super().foo
が与える。
"SystemError: super(): no arguments".
なぜそうなるのか、誰か説明してください。
どのように解決するのですか?
あなたは
ではなく
使用
self.__class__
または
type(self)
を呼び出したとき
super()
.
Python 3 では
super()
引数なしは、以下のものと同じです。
super(B, self)
(クラス上のメソッド内で
B
); 注意すべきは
明示的な
という名前を付けています。Pythonコンパイラは
__class__
を使用するメソッドには、クロージャセル
super()
引数なしで (
Python 3.xのsuper()はなぜ魔法なのですか?
を参照する)。
現在のクラス
が定義されています。
を使用する場合
super(self.__class__, self)
または
super(type(self), self)
を使用すると、サブクラスがそのメソッドを呼び出そうとしたときに無限再帰例外が発生します。
self.__class__
は
派生クラス
であり、オリジナルではない。参照
派生クラスでsuper()を呼び出すとき、self.__class__を渡してもいいのでしょうか?
ということで、まとめると、Python3では。
class B(A):
def __init__(self):
print("B __init__")
super().__init__()
def foo(self):
print("B foo")
super().foo()
が等しい。
class B(A):
def __init__(self):
print("B __init__")
super(B, self).__init__()
def foo(self):
print("B foo")
super(B, self).foo()
が、前者を使った方が、同じことを繰り返さずに済みます。
Python 2 では、2 番目の形式である のみ .
あなたのために
bind_foo()
Python コンパイラは、新しい置換オブジェクトをバインドするときにどのクラスが使われるかを判断できないからです。
foo
:
def bind_foo(self, klass=None):
old_foo = self.foo
if klass is None:
klass = type(self)
def new_foo():
old_foo()
super(klass, self).foo()
self.foo = new_foo
あなた
可能
使用
__class__
(いいえ
self
への参照となり、Pythonはクロージャーセルを提供します。
A
ではなく
C
をここに示します。新しい
foo
で検索を開始し、MRO でオーバーライドされたメソッドを検索したい場合。
C
の代わりに
ここで、もしあなたがクラス
D
をサブクラス化したものです。
C
うまくいかない
また
というのは、今、あなたは
bind_foo()
を呼び出し、次に
super()
で
D
でなく
C
を開始点とします。その場合、最善の策は
bind_foo()
を使用しています。
明示的
クラスの参照になります。ここでは
__class__
(いいえ
self.
を使用するとうまくいきます。
class C(A):
def __init__(self):
print("C __init__")
super().__init__()
self.bind_foo(__class__)
を使用した場合と同じ動作になります。
super()
を引数なしで参照すると
現在の
クラス、つまりメソッドを定義しているクラスです。
__init__
に渡されます。
super()
を作成します。
new_foo()
のクラス定義の中で直接定義されているかのように振る舞います。
C
.
を呼び出す意味がないことに注意してください。
bind_foo()
で
super()
ここではオーバーライドしていないので、単に
self.bind_foo()
の代わりに
関連
-
[解決済み] staticmethodとclassmethodの違いについて
-
[解決済み] Pythonのリストメソッドであるappendとextendの違いは何ですか?
-
[解決済み] 自分」という言葉は何のためにあるのか?
-
[解決済み] 私的相続、公的相続、保護相続の違いについて
-
[解決済み] Pythonの旧スタイルのクラスと新スタイルのクラスの違いは何ですか?
-
[解決済み] Pythonで子クラスから親クラスのメソッドを呼び出すにはどうすればよいですか?
-
[解決済み] Pythonで'super'は何をするのですか?- super().__init__() と明示的なスーパークラス __init__() の違い
-
[解決済み】__str__と__repr__の違いは何ですか?
-
[解決済み】venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, pipenvなどの違いは何ですか?
-
[解決済み】type()とisinstance()の違いは何ですか?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
PicgoのイメージベッドツールをPythonで実装する
-
Python カメの描画コマンドとその例
-
Python interpreted model libraryによる機械学習モデル出力の可視化 Shap
-
[解決済み] データ型が理解できない
-
[解決済み】TypeErrorを取得しました。エントリを持つ子テーブルの後に親テーブルを追加しようとすると、 __init__() missing 1 required positional argument: 'on_delete'
-
[解決済み】Pythonでgoogle APIのJSONコードを読み込むとエラーになる件
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】django インポートエラー - core.managementという名前のモジュールがない
-
[解決済み] Python 3.xのsuper()はなぜ魔法なのか?
-
[解決済み] 子クラスからベースクラスの __init__ メソッドを呼び出すには?重複