Enum的使用记录。

参考链接: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)
posted @ 2020-01-17 03:30  就是想学习  阅读(243)  评论(0编辑  收藏  举报