使用ABC,PolymorphicModel,django-models提供元类冲突 [英] Using ABC, PolymorphicModel, django-models gives metaclass conflict

查看:210
本文介绍了使用ABC,PolymorphicModel,django-models提供元类冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,SO答案上的所有其他答案都以完全相同的方式进行:构造您的元类,然后继承这些元类的联接"版本,即

So far every other answer on SO answers in the exact same way: construct your metaclasses and then inherit the 'joined' version of those metaclasses, i.e.

class M_A(type): pass
class M_B(type): pass
class A(metaclass=M_A): pass
class B(metaclass=M_B): pass

class M_C(M_A, M_B): pass
class C:(A, B, metaclass=M_C): pass

但是我不知道这些人所生活的世界是什么,他们正在构建自己的元类!显然,人们会使用其他库中的类,除非您对元编程有一个完美的了解,否则如何知道是否可以重写类的元类呢? (很明显,我还没有办法解决这个问题.)

But I don't know what world these people are living in, where they're constructing your own metaclasses! Obviously, one would be using classes from other libraries and unless you have a perfect handle on meta programming, how are you supposed to know whether you can just override a class's metaclass? (Clearly I do not have a handle on them yet).

我的问题是:

class InterfaceToTransactions(ABC):
    def account(self):
        return None
    ...

class Category(PolymorphicModel, InterfaceToTransactions):
    def account(self):
        return self.source_account
    ...

class Income(TimeStampedModel, InterfaceToTransactions):
    def account(self):
        return self.destination_account
    ...

当然会给我一个错误:元类冲突:派生类的元类必须是其所有基元元类的(非严格)子类" 我已经尝试了上面给出的解决方案的许多变体,但以下内容不起作用,并给出了相同的错误.

Which of course gives me the error: "metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases" I've tried many variations of the solution given above, the following does not work, gives the same error.

class InterfaceToTransactionsIntermediaryMeta(type(PolymorphicModel), type(InterfaceToTransactions)):
pass

class Category(PolymorphicModel, InterfaceToTransactions):
    __metaclass__ = InterfaceToTransactionsIntermediaryMeta
    ...

Nor不会在类Meta函数中放入任何内容.我已经阅读了有关此主题的所有其他问题,请不要简单地将其标记为重复.

Nor does putting anything inside the class Meta function. I've read every single other SO question on this topic, please don't simply mark it as duplicate.

-------------------接受解决方案后于1/8/18编辑-------

奇怪的是,如果我尝试使用这种新配置(我接受的配置)进行迁移,它将再次开始出现元类错误,但在运行时仍然可以使用.如果我注释掉元类部分,然后进行迁移和迁移,它将成功完成,但是每次迁移之后,我都必须将其放回原处.

Oddly enough, if I try to makemigrations with this new configuration (the one I accepted), it starts giving the metaclass error again, but it still works during runtime. If I comment out the metaclass parts then makemigrations and migrate, it will do it successfully, but then I have to put it back in there after migrating every time.

推荐答案

如果您使用的是Python 3,则您将尝试错误地使用派生的元类.

If you are using Python 3, you are trying to use your derived metaclass incorrectly.

并且由于您得到相同的错误",而不是其他可能的,更微妙的错误,所以我会说这是正在发生的事情.

And since you get "the same error", and not other possible, more subtle, error, I'd say this is what is happening.

尝试仅更改为:

class IntermediaryMeta(type(InterfaceToTransactions), type(PolymorphicModel)):
    pass

class Category(PolymorphicModel, InterfaceToTransactions, metaclass=IntermediaryMeta):
    ...

(至少可以保证ABCMeta类使用super协同工作,这足以使该类首先基于) 元组)

(At least the ABCMeta class is guaranteed to work collaboratively using super, that is enough motive to place the classe it first on the bases ) tuple)

如果这给您带来了新的改进错误,则意味着这两个类中的一个或两个由于某种动机之一而无法真正正确地协作.然后,要走的路是迫使不依赖ABCMeta的继承树这样做,因为它的作用几乎是美观的,在这种语言中,其他所有东西都用于同意成年人"的Python.

If that yields you new and improved errors, this means that one or both of those classes can't really collaborate properly due to one of several motives. Then, the way to go is to force your inheritance tree that depends on ABCMeta not to do so, since its role is almost aesthetical in a language where everything else is for "consenting adults" like Python.

不幸的是,方法是使用各种暴力手段,从安全的重新写入所有内容"到猴子补丁ABCMeta以及在"InterfaceToTransactions"被定义为什么都不做的地方的抽象方法.

Unfortunatelly, the way to that is to use varying methods of brute-force, from safe "rewritting everything" to monkey patching ABCMeta and abstractmethod on the place were "InterfaceToTransactions" is defined to simply do nothing.

如果您需要到达那里并需要一些帮助,请发布另一个问题.

If you need to get there, and need some help, please post another question.

对不起-这实际上是使用元类的主要缺点.

Sorry - this is actually the major drawbacks of using metaclasses.

这篇关于使用ABC,PolymorphicModel,django-models提供元类冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆