如何对Python Enum mixin类进行Cythonize?

2024-05-18 10:53:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Enum mixin(serde_枚举.py)将转储/加载方法添加到枚举以进行序列化/反序列化的类型,如下所示:

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(以加速慢加载/转储代码),它会破坏枚举。这是我的密码(serde_枚举.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类的enum,也会发生同样的情况


Tags: inimportapplevaluedeftypegreenenum