Python 将类拆分为单独的文件时发生元类冲突 编辑
问题在于进口。我应该做的是写:Python 将类拆分为单独的文件时发生元类冲突 编辑,python,sqlalchemy,Python,Sqlalchemy,问题在于进口。我应该做的是写:从SomeInterface导入SomeInterface。实际上,我应该用小写的someinterface.py按照编写模块名 我有一个文件model.py定义了与我的数据库相关的所有类,并实例化了我的数据库 # model.py metadata = MetaData() DeclarativeBase = declarative_base() metadata = DeclarativeBase.metadata class Bar(Declarative
从SomeInterface导入SomeInterface
。实际上,我应该用小写的someinterface.py
按照编写模块名
我有一个文件
model.py
定义了与我的数据库相关的所有类,并实例化了我的数据库
# model.py
metadata = MetaData()
DeclarativeBase = declarative_base()
metadata = DeclarativeBase.metadata
class Bar(DeclarativeBase):
__tablename__ = 'Bar'
__table_args__ = {}
# column and relation definitions
文件model.py
是自动生成的,因此我无法真正触摸它。我所做的是创建一个名为modelaungmented.py
的文件,通过继承向一些模型类添加额外的功能
# modelaugmented.py
from model import *
import SomeInterface
class BarAugmented(Bar, SomeInterface):
pass
# SomeInterface.py
class SomeInterface(object):
some_method(): pass
我遇到的问题是,对于像BarAugmented
这样的类,我得到以下错误:
TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
只有当SomeInterface
位于单独的文件中而不是modelaugmented.py
中时,我才会出现此错误
我知道SomeInterface
和Bar
的元类是不同的。问题是我不知道如何解决这个问题。我尝试了在给出的示例中有效的建议解决方案,但在我的案例中没有。不确定SqlAlchmey是否与此有关
class MetaAB(type(DeclarativeBase), type(SomeInterface)):
pass
class BarAugmented(Bar, SomeInterface):
__metaclass__ = MetaAB
但是我得到了一个错误:
TypeError: Error when calling the metaclass
bases multiple bases have instance lay-out conflict
使用SQLAlchemy 0.8和Python 2.7。好的,我肯定遗漏了什么,因为我创建了一个与您类似的文件布局(我想),并且它可以在我的机器上运行。我很感激你让你的问题简短明了,但可能是遗漏了一些改变。。。某物不知道(也许
SomeInterface
有一个abc.abstract
元类?)如果你更新了你的问题,请通过对这个答案的评论让我知道,我会尝试更新我的答案
下面是:
文件stack29A.py
(相当于您的model.py
):
文件
stack29B.py
(相当于您的someinterface.py
):
文件
stack29C.py
(相当于您的modelaugmented.py
):
文件
stack29D.py
(类似于main.py
:表创建者和示例):
如果我运行“main”文件(stack29D.py
),则一切正常:
(venv_SO)borrajax@borrajax:~/Documents/Tests$ python ./stack29D.py
b3.email: foo@bar.baz
hellou
是的。。。你面临着多重继承的问题。还有一个问题。。。在
BarAugmented
中,它必须将数据保存到的表是什么?表foo
?表条形图
?您真的需要这种模式吗?(只是问一下,但对于任何ORM来说,这看起来都是一个非常复杂的结构,需要正确处理)@BorrajaX说得很对。我编辑了我的问题。。。看来问题不在炼金术中。。。看看这个:而且(我刚刚找到了那些链接,我不知道它们是否有用)你能试试非声明性声明吗?(只需声明您的表,然后声明您的类,然后声明您的映射)?@BorrajaX感谢您的链接。我之前尝试过,但不幸的是,我得到了错误“SomeInterface”没有属性“\u decl\u class\u registry”
。对此我很抱歉:-(那么我会选择非声明性的。执行声明性模型可能会改变您的类\u元类\uuuuu
(不过,请等待真正的答案……无论如何,您可能不需要这样做)谢谢@BorrajaX。真的很有帮助。试着找出我的为什么不起作用。这可能是因为我的SomeInterface
有执行会话查询的方法(但它仍然继承自object)。我会找出它并报告回来。是的,这很奇怪…这不会改变元类…是的,让我知道。我现在很好奇:-)非常尴尬。问题在于进口。我应该做的是写:从SomeInterface导入SomeInterface
。我对Python比较陌生。很高兴我在某种程度上帮了忙。。。(不知何故……因为我希望我帮助解决了问题,而不是我解决了问题):-D
class SomeInterface(object):
def some_method(self):
print "hellou"
from stack29A import Bar
from stack29B import SomeInterface
class BarAugmented(Bar, SomeInterface):
pass
from stack29C import BarAugmented
from stack29A import session, engine, DeclarativeBase
if __name__ == "__main__":
DeclarativeBase.metadata.create_all(engine)
b1 = BarAugmented()
b1.email = "foo@bar.baz"
b2 = BarAugmented()
b2.email = "baz@bar.foo"
session.add_all([b1, b2])
session.commit()
b3 = session.query(BarAugmented)\
.filter(BarAugmented.email == "foo@bar.baz")\
.first()
print "b3.email: %s" % b3.email
b3.some_method()
(venv_SO)borrajax@borrajax:~/Documents/Tests$ python ./stack29D.py
b3.email: foo@bar.baz
hellou