クラス(デフォルトでは)type
のインスタンスであるべきです。 クラスFoo
のインスタンスがfoo = Foo(...)
によって作成されたのと同様に、type
(つまりクラス)のインスタンスがmyclass = type(name, bases, clsdict)
によって作成されます。
クラス作成の時点で特別なことが起こりたい場合は、クラスを作成するものを変更する必要があります。つまり、type
です。これを行う方法は、type
のサブクラス、つまりメタクラスを定義することです。
メタクラスは、そのインスタンスがクラスであるため、クラスに属します。
はPython2では、Watcher
がtype
のサブクラスである
class SuperClass:
__metaclass__ = Watcher
でクラスのメタクラスを定義します。
のpython3で構文はどちらも、この場合には、name
が文字列'Superclass'
に等しく、bases
タプル(object,)
ある
Superclass = Watcher(name, bases, clsdict)
に相当する
class SuperClass(metaclass=Watcher)
に変更されました。 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
メタクラスを使用します。メタクラスは、インスタンスの作成時にクラスが呼び出されるのと同じように、クラスが作成されるときに呼び出されます。 –
は答えを追加することはできませんが、今日のpython3.6は '__init_subclass__'を持っている - それをチェックアウト! –
@OrDuan:ありがとう、役に立つ音。私の問題のために "メタクラスを使う"の代わりに専用の解決策があるので、この質問の重複を解消するのに十分な理由があるかもしれません。 –