【问题标题】:Resolving enum34 metaclass conflict?解决 enum34 元类冲突?
【发布时间】: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。不知道如何解决这个问题,这一切都变得非常复杂。
  • 我在评论中写给你如何解决这个问题。

标签: python enums metaclass


【解决方案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):
    猜你喜欢
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 2013-10-19
    • 1970-01-01
    • 2012-03-01
    相关资源
    最近更新 更多