解决 enum34 元类冲突?

Posted

技术标签:

【中文标题】解决 enum34 元类冲突?【英文标题】:Resolving enum34 metaclass conflict? 【发布时间】:2015-05-19 13:33:20 【问题描述】:

有没有办法让自定义元类与 enum34 包(Python 3 之前)配合得很好?

import enum
import six

class MyMeta(type):
    def __new__(cls, class_name, bases, class_dict):
        print("Does something useful.")
        return super(MyMeta, cls).__new__(cls, class_name, bases, class_dict)

@six.add_metaclass(MyMeta)
class MyClass(object):
    def __init__(self, *args, **kwargs):
        pass

MyEnum = enum.Enum('MyEnum', [('One', 1), ('Two', 2), ('Three', 3)], type=MyClass)

以上内容目前在enum_class = super(EnumMeta, metacls).__new__(metacls, cls, bases, classdict) 的 enum34 中引发错误:

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

【问题讨论】:

你想达到什么目的?为什么需要 mixin? 嗯,基本上我希望创建一个枚举,其值是从自定义类型派生的。不幸的是,有问题的类型有一个元类,这就是麻烦的开始。我想我只需要将我的值放入字典或其他东西中。 你可以从两个元类派生MyMeta,但我个人不喜欢新的枚举并且会避免它们。 就像我说的,一旦我从enum.EnumMeta 派生出MyMeta,我就会得到另一个错误。我猜enum.EnumMeta.__new__ 在基类中寻找enum.Enum。不知道如何解决这个问题,这一切都变得非常复杂。 我在评论中写给你如何解决这个问题。 【参考方案1】:

而不是 enum.Enum。你应该只写枚举。那个问题就解决了。

例如:

        class MyEnumClass(Enum):
               ........

【讨论】:

【参考方案2】:

您应该从enum.Enum 的元类派生MyMeta

class MyMeta(type(enum.Enum)):
    ...

【讨论】:

谢谢,但不幸的是这不起作用。相反,您会收到以下错误:TypeError: new enumerations must be created as 'ClassName([mixin_type,] enum_type)'. 我猜这是 Enum34 对 Python 2 的限制。根据文档,Enumtype 参数是“混合到新 Enum 类的类型”。如果您需要 mixin,请执行(如消息所示):class MyEnum(MyClass, enum.Enum):

以上是关于解决 enum34 元类冲突?的主要内容,如果未能解决你的问题,请参考以下文章

flask-classy 和 peewee,元类冲突错误

Python 元类冲突

为啥具有对象基础的元类会引发元类冲突?

结合 Qgraphics 和 sqlalchemy 时出现元类错误

TypeError:元类冲突:派生类的元类

04-git-解决冲突与异常