2016-05-12 127 views
1

我有一個Python枚舉這樣的:如何在枚舉類型中定義枚舉成員的映射?

from enum import Enum, unique 

@unique 
class Levels(Enum): 
    Unknown = 0 
    Warning = 1 
    Error = 2 

    def __eq__(self, other): return self.value == other.value 
    def __ne__(self, other): return self.value != other.value 
    def __lt__(self, other): return self.value < other.value 
    def __le__(self, other): return self.value <= other.value 
    def __gt__(self, other): return self.value > other.value 
    def __ge__(self, other): return self.value >= other.value 

    __MAPPPING__ = { 
    "warn": Warning, 
    "error": Error 
    } 

    @classmethod 
    def Parse(cls, value, default=None): 
    return cls.__MAPPPING__.get(value, default) 

在本例中,我已經提取出的映射到一個類的成員(根據timeit.timeit(),其更快)。

我現在的問題是,字典值是使用原始的枚舉成員值(整數),而不是創建的枚舉成員(EnumMeta)。這是合理的,因爲當dict被構造時,它不存在。

如何/在哪裏可以鉤入Enum類/ EnumMeta類或我自己的Levels類,以便使用創建的枚舉成員修補字典?

回答

1

[只顯示相關的片...]

@unique 
class Levels(Enum): 
    Unknown = 0 
    Warning = 1 
    Error = 2 

    __MAPPPING__ = { 
     "warn": Warning, 
     "error": Error 
    } 

    def __init__(self, *args): 
     """Patch the embedded MAP dictionary""" 
     self.__class__.__MAPPPING__[self._name_] = self 

__init__是呼籲各成員已被創建之後,所以在這一點上,你可以使用成員名稱作爲關鍵更新__MAPPING__ 。如果你使用這種模式有很多,你應該考慮使用其他裝飾:

def add_mapping(enum_cls): 
    for name in enum_cls.__MAPPING__: 
     member = enum_cls.__members__[name] 
     enum_cls.__MAPPING__[name] = member 
    return enum_cls 

,並在使用中:

@add_mapping 
@unique 
class Levels(Enum): 
    Unknown = 0 
    Warning = ... 
+0

我改進了一點你的解決方案,因爲,預期的枚舉成員是字典中的值。因此,如果在映射中定義了每個__init__調用,則會掃描該詞典並用枚舉成員替換值(int)。 – Paebbels

+1

@帕培爾:啊,我誤解了那部分。簡化你的代碼並更新裝飾器。 –

+0

@Paebbels:如果這僅僅是一個性能增強,爲什麼你不把所有的成員?而且,在3.5中,大部分(如果不是全部)性能命中被刪除。 –

0

要建立在Mr. Furman's提供above,一個map_value(name)方法來獲取映射:

add_mapping(enum_cls): 
    enum_cls.__MAPPING__ = {e.value: e for e in enum_cls} 
    enum_cls.map_value = lambda name, default=None: enum_cls.__MAPPING__.get(name, default) 
    return enum_cls 
+0

我批准了你的編輯到我的答案,謝謝你的捕捉。現在,如果我們可以讓編輯不拒絕錯誤修復代碼,他們不明白。 :( –