如何对Python Enum mixin类进行Cythonize?

时间:2019-05-12 13:44:15

标签: python cython

我有一个Enum mixin(serde_enum.py)类型,它将转储/装入方法添加到Enum中进行序列化/反序列化,如下所示:

from enum import Enum

class Primitive:

    def load(self):
        pass

    def dump(self):
        pass

我可以像这样创建一个枚举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类进行cythonize(以加快慢速加载/转储代码),它将破坏枚举。这是我的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

如果我通过使用上面定义的SerDeEnum类(例如Apple = serde_enum.SerDeEnum('Apple', ['RED', 'GREEN', 'BLUE'])

)通过继承创建带有mixin类的枚举,则会发生同样的事情

0 个答案:

没有答案