クラスがサブクラス化されたときにコードを実行するにはどうすればいいですか? [重複] 質問する

クラスがサブクラス化されたときにコードを実行するにはどうすればいいですか? [重複] 質問する

クラスがサブクラス化されたときにコードをトリガーする方法はありますか?

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

ベストアンサー1

クラスは(デフォルトでは) のインスタンスです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

おすすめ記事