django 模型对 abc 进行子类化,导致元类冲突

发布于 2024-12-24 21:04:49 字数 876 浏览 5 评论 0 原文

我有一个以下模型和抽象基类

import abc
from django.db import models


class AbstractBase():
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def my_method(self):
        return


class MyModel(models.Model, AbstractBase):
    @abc.abstractmethod
    def my_method(self):
        return 1

但我收到以下错误。

元类冲突:派生类的元类必须是 (非严格)其所有基类的元类的子类

我认为这里的问题是(正如这里所描述的http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/)两个不同的元类,因此 python 无法决定将哪个元类用于子对象。

为了解决这个问题,我删除了多重继承并使用以下注册方法来注册子类,

abc.register(Child)

但我不太喜欢这种方法,因为它看起来像猴子修补。

还有其他方法可以解决这个问题吗?

我尝试将模型元类显式分配给 Child 但它不起作用。 我并不是在寻找通过编写代码来解决它的方法。我认为这个问题必须通过改变我的班级结构来解决。

I have a following model and abstract base class

import abc
from django.db import models


class AbstractBase():
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def my_method(self):
        return


class MyModel(models.Model, AbstractBase):
    @abc.abstractmethod
    def my_method(self):
        return 1

But I am getting the following error.

metaclass conflict: the metaclass of a derived class must be a
(non-strict) subclass of the metaclasses of all its bases

I think the problem here is (As it is described here http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/) that two base class has two different metaclasses so python cannot decide which metaclass to use for child object.

In order to solve this I removed multiple inheritence and use following register method to register child class

abc.register(Child)

But I did not really like this approach since it looks like monkey patching.

Is there another way to solve this problem?

I try to assign Model metaclass to Child explicitly but it did not work.
I am not looking for a way to solve it by writing code. I think this must be solved by changing my class structure.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

故事还在继续 2024-12-31 21:04:49

除了创建一个继承自 ABCMetaModelBase 的新元类之外,或使 ABCMeta 继承自 ModelBase >, 您无能为力。

但是,不同的注册模式可能是合适的吗? 也许像contrib.admin.autodiscover或者类装饰器?或者在 .py 文件底部的一个循环,它在适当的类上调用 register (例如,for var in globals().values(): if isinstance(var, type) 和 issubclass(var, AbastractBase): register(var))?

编辑:哦。我假设 ABCMeta 是一个例子,而不是 <代码>ABCMeta。这就是我在睡眠不足的情况下浏览 StackOverflow 所得到的结果。

Apart from creating a new metaclass that inherits from both ABCMeta and ModelBase, or making ABCMeta inherit from ModelBase, there isn't much you can do.

However, possibly a different registration pattern might be appropriate? Maybe something like contrib.admin.autodiscover? Or a class decorator? Or a loop at the bottom of the .py file which calls register on the appropriate classes (ex, for var in globals().values(): if isinstance(var, type) and issubclass(var, AbastractBase): register(var))?

Edit: D'oh. I'd assumed that ABCMeta was an example, not ABCMeta. That's what I get for browsing StackOverflow on too little sleep.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文