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