У меня есть тип Enum mixin (serde_enum.py), который добавляет методы дампа / загрузки в Enum для сериализации / десериализации, который выглядит примерно так:
from enum import Enum
class Primitive:
def load(self):
pass
def dump(self):
pass
Я могу создать Enum Apple
, например, с дополнительными load()
и dump()
методами:
In [1]: import serde_enum
In [2]: from enum import Enum
In [3]: Apple = Enum('Apple', ['RED', 'GREEN', 'BLUE'], type=serde_enum.Primitive)
In [4]: Apple.__members__
Out[4]:
mappingproxy({'RED': <Apple.RED: 1>,
'GREEN': <Apple.GREEN: 2>,
'BLUE': <Apple.BLUE: 3>})
In [5]: Apple.RED.dump
Out[5]: <bound method Primitive.dump of <Apple.RED: 1>>
In [6]: r = Apple(1)
Теперь, если я попытаюсь цитонизировать класс mixin (чтобы ускорить медленный код загрузки / выгрузки), он нарушит перечисление. Вот мой код Cython (serde_enum.pyx):
# cython: language_level=3
from enum import Enum
cdef class Primitive:
cpdef load(self):
pass
cpdef dump(self):
pass
class SerDeEnum(Primitive, Enum):
pass
но сейчас:
In [1]: from enum import Enum
In [2]: import serde_enum
In [3]: Apple = Enum('Apple', ['RED', 'GREEN', 'BLUE'], type=serde_enum.Primitive)
In [4]: Apple.__members__
Out[4]:
mappingproxy({'RED': <Apple.RED: <serde_enum.Primitive object at 0x7ff91adc2ea0>>,
'GREEN': <Apple.GREEN: <serde_enum.Primitive object at 0x7ff91adc2eb0>>,
'BLUE': <Apple.BLUE: <serde_enum.Primitive object at 0x7ff91adc2ec0>>})
In [5]: Apple.RED.dump
Out[5]: <function Apple.dump>
In [6]: r = Apple(1)
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-6-670cfcdec304> in <module>
----> 1 r = Apple(1)
/usr/lib/python3.6/enum.py in __call__(cls, value, names, module, qualname, type, start)
291 """
292 if names is None: # simple value lookup
--> 293 return cls.__new__(cls, value)
294 # otherwise, functional API: we're creating a new Enum type
295 return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start)
/usr/lib/python3.6/enum.py in __new__(cls, value)
533 return member
534 # still not found -- try _missing_ hook
--> 535 return cls._missing_(value)
536
537 def _generate_next_value_(name, start, count, last_values):
/usr/lib/python3.6/enum.py in _missing_(cls, value)
546 @classmethod
547 def _missing_(cls, value):
--> 548 raise ValueError("%r is not a valid %s" % (value, cls.__name__))
549
550 def __repr__(self):
ValueError: 1 is not a valid Apple
То же самое происходит, если я создаю перечисление с классом mixin по наследству, используя SerDeEnum
класс I, определенный выше, как Apple = serde_enum.SerDeEnum('Apple', ['RED', 'GREEN', 'BLUE'])