SqlAlchemyのクラス構築プロセスで自分のコードの一部を挿入しようとしています。コードを理解しようとすると、メタクラスの実装に少し混乱します。関連するスニペットは次のとおりです。
SqlAlchemyのデフォルトの「メタクラス」:
class DeclarativeMeta(type):
def __init__(cls, classname, bases, dict_):
if '_decl_class_registry' in cls.__dict__:
return type.__init__(cls, classname, bases, dict_)
else:
_as_declarative(cls, classname, cls.__dict__)
return type.__init__(cls, classname, bases, dict_)
def __setattr__(cls, key, value):
_add_attribute(cls, key, value)
declarative_base
このように実装されます:
def declarative_base(bind=None, metadata=None, mapper=None, cls=object,
name='Base', constructor=_declarative_constructor,
class_registry=None,
metaclass=DeclarativeMeta):
# some code which should not matter here
return metaclass(name, bases, class_dict)
これは次のように使用されます:
Base = declarative_base()
class SomeModel(Base):
pass
これで、次のような独自のメタクラスを派生させました。
class MyDeclarativeMeta(DeclarativeMeta):
def __init__(cls, classname, bases, dict_):
result = DeclarativeMeta.__init__(cls, classname, bases, dict_)
print result
# here I would add my custom code, which does not work
return result
そして、次のように使用します。
Base = declarative_base(metaclass=MyDeclarativeMeta)
さて、私の問題です:
print result
私自身のクラスでは常に印刷しNone
ます。- コードはとにかく動作するようです!?
- メタクラスが使用しているのはなぜ
__init__
ですか__new__
declarative_base
このクラスのインスタンスを返します。__metaclass__
値として属性を持つクラスを返すべきではありませんMyDeclarativeMeta
か?
それで、なぜコードがまったく機能するのか疑問に思います。SqlAlchemyの人々は明らかに彼らが何をしているのかを知っているので、私は完全に間違った方向に進んでいると思います。誰かがここで何が起こっているのか説明できますか?