我正在尝试在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 人显然知道他们在做什么,我认为我完全走错了轨道。有人可以解释这里发生了什么吗?