1. 程式人生 > 實用技巧 >自定義帶描述欄位的Python列舉

自定義帶描述欄位的Python列舉

#!/usr/local/bin/python3
# -*- coding: utf-8 -*-

__author__ = "Carp-Li"
__date__ = "2020/10/18"

from enum import Enum
from collections import namedtuple
from types import DynamicClassAttribute


T = namedtuple("Field", ["value", "desc"])


class FieldEnum(Enum):

    @DynamicClassAttribute
    def value(self):
        """ 直接獲取namedtuple的value的值 """
        return self._value_.value

    @DynamicClassAttribute
    def desc(self):
        """ 直接獲取namedtuple的desc的值 """
        return self._value_.desc

    @classmethod
    def by(cls, value):
        """ 根據value獲取對應的列舉 """
        for field, enum in cls._value2member_map_.items():
            if value == field.value:
                return enum
        raise ValueError(f"{cls.__name__}(value={value}):沒有對應的列舉")

    @classmethod
    def by_desc(cls, text):
        """ 根據desc獲取對應的列舉 """
        for field, enum in cls._value2member_map_.items():
            if text == field.desc:
                return enum
        raise ValueError(f"{cls.__name__}(desc={text}):沒有對應的列舉")

    @DynamicClassAttribute
    def field(self):
        """ 返回一個namedtuple """
        return self._value_

    @classmethod
    def iter_field(cls):
        """ 返回一個迭代器物件,方便遍歷 """
        for field in cls._value2member_map_.keys():
            yield field


class Gender(FieldEnum):
    """ 一個例子 """
    MAN = T(1, "男")
    WOMAN = T(2, "女")
    NULL = T(0, "未知")


if __name__ == '__main__':
    print(Gender.by(0))
    print(Gender.by_desc("男"))