参考链接:Python_枚举
我自己的使用感受,枚举就像定义了一套变量赋值关系,这套赋值关系就一个对象,你可以通过对象里面的key或者value来找到对象本身。
使用起来还时蛮有意思的。
使用中,你可以通过创建类,继承使用。或者直接通过Enum('xx','xxx xxx xxx')来使用。
首先通过创建类来使用:
In [71]: class My_Enum(Enum): ...: name = 'sidian' ...: age = 18 ...: adde = 'hangzhou' ...: In [72]: My_Enum.name # 通过类属性来知道关系对象 Out[72]: <My_Enum.name: 'sidian'> In [73]: dir(My_Enum.name) # 产看对象的一些属性,竟然没有看到那么的属性 Out[73]: ['__class__', '__doc__', '__module__', 'value'] In [74]: My_Enum.name.value # 查看对象的值 Out[74]: 'sidian' In [75]: My_Enum('sidian') # 通过实例化值来找到关系对象实例 Out[75]: <My_Enum.name: 'sidian'> In [76]: x = My_Enum('sidian') In [77]: x Out[77]: <My_Enum.name: 'sidian'> In [78]: dir(x) Out[78]: ['__class__', '__doc__', '__module__', 'value'] In [79]: x.name # 虽然没有name属性,但从name属性还时拿到了关系对象的name Out[79]: 'name' In [80]: dir(My_Enum) Out[80]: ['__class__', '__doc__', '__members__', '__module__', 'adde', 'age', 'name'] In [81]: My_Enum.__members__ # 通过__members__属性可以看到内部的成员为不可变的字典,key为类属性的字符串形式,value为关系对象。 Out[81]: mappingproxy({'name': <My_Enum.name: 'sidian'>, 'age': <My_Enum.age: 18>, 'adde': <My_Enum.adde: 'hangzhou'>}) In [82]:
还有一种就是直接实例化Enum类
In [88]: my_son = Enum('son','dabao erbao sanbao') In [89]: my_son # 通过实例化创建对象 Out[89]: <enum 'son'> In [90]: My_Enum # 对前面通过继承的类名调用,发现该类名已经是Enum的实例,Enum给我的感觉像类元。 Out[90]: <enum 'My_Enum'> In [91]: my_son.__members__ # Enum里面的参数,第一个是实例后的对象名称,后面的参数空格会自动切割,然后自动给分割后的变量名复制,复制初始值从1开始 Out[91]: mappingproxy({'dabao': <son.dabao: 1>, 'erbao': <son.erbao: 2>, 'sanbao': <son.sanbao: 3>}) In [92]: my_son(2) # 通过值寻找关系对象 Out[92]: <son.erbao: 2> In [93]: my_son(2).name Out[93]: 'erbao' In [94]: my_love = Enum('love',['l1','l2']) # 实例化的第二个参数也可以通过列表进行传入 In [95]: my_love Out[95]: <enum 'love'> In [96]: my_love(1) Out[96]: <love.l1: 1> In [97]: my_love(2) Out[97]: <love.l2: 2> In [98]:
In [100]: Enum? Init signature: Enum(value, names=None, *, module=None, qualname=None, type=None, start=1) Docstring: Generic enumeration. Derive from this class to define new enumerations. File: /usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/enum.py Type: EnumMeta Subclasses: IntEnum, Flag, Purpose, _SendfileMode, SortKey, s, Color, 12, Status, Gender, ... In [101]:
下面上原码
Init signature: Enum(value, names=None, *, module=None, qualname=None, type=None, start=1) Source: class Enum(metaclass=EnumMeta): """Generic enumeration. Derive from this class to define new enumerations. """ def __new__(cls, value): # all enum instances are actually created during class construction # without calling this method; this method is called by the metaclass' # __call__ (i.e. Color(3) ), and by pickle if type(value) is cls: # For lookups like Color(Color.RED) return value # by-value search for a matching enum member # see if it's in the reverse mapping (for hashable values) try: return cls._value2member_map_[value] except KeyError: # Not found, no need to do long O(n) search pass except TypeError: # not there, now do long search -- O(n) behavior for member in cls._member_map_.values(): if member._value_ == value: return member # still not found -- try _missing_ hook try: exc = None result = cls._missing_(value) except Exception as e: exc = e result = None if isinstance(result, cls): return result else: ve_exc = ValueError("%r is not a valid %s" % (value, cls.__name__)) if result is None and exc is None: raise ve_exc elif exc is None: exc = TypeError( 'error in %s._missing_: returned %r instead of None or a valid member' % (cls.__name__, result) ) exc.__context__ = ve_exc raise exc def _generate_next_value_(name, start, count, last_values): for last_value in reversed(last_values): try: return last_value + 1 except TypeError: pass else: return start @classmethod def _missing_(cls, value): raise ValueError("%r is not a valid %s" % (value, cls.__name__)) def __repr__(self): return "<%s.%s: %r>" % ( self.__class__.__name__, self._name_, self._value_) def __str__(self): return "%s.%s" % (self.__class__.__name__, self._name_) def __dir__(self): added_behavior = [ m for cls in self.__class__.mro() for m in cls.__dict__ if m[0] != '_' and m not in self._member_map_ ] return (['__class__', '__doc__', '__module__'] + added_behavior) def __format__(self, format_spec): # mixed-in Enums should use the mixed-in type's __format__, otherwise # we can get strange results with the Enum name showing up instead of # the value # pure Enum branch if self._member_type_ is object: cls = str val = str(self) # mix-in branch else: cls = self._member_type_ val = self._value_ return cls.__format__(val, format_spec) def __hash__(self): return hash(self._name_) def __reduce_ex__(self, proto): return self.__class__, (self._value_, ) # DynamicClassAttribute is used to provide access to the `name` and # `value` properties of enum members while keeping some measure of # protection from modification, while still allowing for an enumeration # to have members named `name` and `value`. This works because enumeration # members are not set directly on the enum class -- __getattr__ is # used to look them up. @DynamicClassAttribute def name(self): """The name of the Enum member.""" return self._name_ @DynamicClassAttribute def value(self): """The value of the Enum member.""" return self._value_ @classmethod def _convert(cls, name, module, filter, source=None): """ Create a new Enum subclass that replaces a collection of global constants """ # convert all constants from source (or module) that pass filter() to # a new Enum called name, and export the enum and its members back to # module; # also, replace the __reduce_ex__ method so unpickling works in # previous Python versions module_globals = vars(sys.modules[module]) if source: source = vars(source) else: source = module_globals # We use an OrderedDict of sorted source keys so that the # _value2member_map is populated in the same order every time # for a consistent reverse mapping of number to name when there # are multiple names for the same number rather than varying # between runs due to hash randomization of the module dictionary. members = [ (name, source[name]) for name in source.keys() if filter(name)] try: # sort by value members.sort(key=lambda t: (t[1], t[0])) except TypeError: # unless some values aren't comparable, in which case sort by name members.sort(key=lambda t: t[0]) cls = cls(name, members, module=module) cls.__reduce_ex__ = _reduce_ex_by_name module_globals.update(cls.__members__) module_globals[name] = cls return cls File: /usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/enum.py Type: EnumMeta Subclasses: IntEnum, Flag, Purpose, _SendfileMode, SortKey, s, Color, 12, Status, Gender, ... (END)