[解決済み] クラスがサブクラス化されたときにコードを実行するには?重複
2022-06-15 03:24:26
質問
自分のクラスがサブクラス化されたときに、コードをトリガーする方法はありますか?
class SuperClass:
def triggered_routine(subclass):
print("was subclassed by " + subclass.__name__)
magically_register_triggered_routine()
print("foo")
class SubClass0(SuperClass):
pass
print("bar")
class SubClass1(SuperClass):
print("test")
出力すべき
foo
was subclassed by SubClass0
bar
test
was subclassed by SubClass1
どのように解決するのですか?
クラスは(デフォルトでは)インスタンスとして
type
.
クラスのインスタンスと同じように
Foo
によって作成されます。
foo = Foo(...)
,
のインスタンスは
type
(すなわちクラス) は
myclass = type(name, bases, clsdict)
.
もし、クラスが作られた瞬間に何か特別なことを起こしたいのであれば、 クラスを作るものを変更しなければなりません -- すなわち
type
. のサブクラスを定義することです。
type
のサブクラス -- すなわちメタクラスを定義することです。
メタクラスは、クラスがそのインスタンスにそうであるように、そのクラスにそうである。
Python2では、クラスのメタクラスは
class SuperClass:
__metaclass__ = Watcher
ここで
Watcher
のサブクラスです。
type
.
Python3では、構文は次のように変更されました。
class SuperClass(metaclass=Watcher)
と等価である。
Superclass = Watcher(name, bases, clsdict)
ここで、この場合
name
は文字列
'Superclass'
となり、かつ
bases
はタプル
(object, )
. は
clsdict
は、クラス定義の本文で定義されたクラス属性の辞書です。
と似ていることに注意してください。
myclass = type(name, bases, clsdict)
.
というわけで、ちょうどクラスの
__init__
を使ってインスタンスが生成される瞬間のイベントを制御するのと同様に、クラスが生成される瞬間のイベントをメタクラスの
__init__
:
class Watcher(type):
def __init__(cls, name, bases, clsdict):
if len(cls.mro()) > 2:
print("was subclassed by " + name)
super(Watcher, cls).__init__(name, bases, clsdict)
class SuperClass:
__metaclass__ = Watcher
print("foo")
class SubClass0(SuperClass):
pass
print("bar")
class SubClass1(SuperClass):
print("test")
プリント
foo
was subclassed by SubClass0
bar
test
was subclassed by SubClass1
関連
-
Pythonの@decoratorsについてまとめてみました。
-
[解決済み】TypeError: re.findall()でバイトのようなオブジェクトに文字列パターンを使用することはできません。)
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] リストのリストからフラットなリストを作るには?
-
[解決済み] リストが空かどうかを確認するにはどうすればよいですか?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] print()を使用してクラスのインスタンスを表示するには?
-
[解決済み] pytestの実行中に作成された通常の印刷出力を見るにはどうすればよいですか?
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み】2つの辞書を1つの式でマージする(辞書の和をとる)には?)
最新
-
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 実装 サイバーパンク風ボタン
おすすめ
-
Pythonコンテナのための組み込み汎用関数操作
-
Python百行で韓服サークルの画像クロールを実現する
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
風力制御におけるKS原理を深く理解するためのpythonアルゴリズム
-
[解決済み] _tkinter.TclError: 表示名がなく、$DISPLAY環境変数もない。
-
[解決済み】socket.error: [Errno 48] アドレスはすでに使用中です。
-
[解決済み】 AttributeError: モジュール 'matplotlib' には属性 'plot' がない。
-
[解決済み】Python elifの構文が無効です【終了しました
-
[解決済み】インポートエラー。モジュール名 urllib2 がない
-
[解決済み】ImportError: bs4という名前のモジュールがない(BeautifulSoup)