python中enum_关于python中Enum的个人总结

  • Post author:
  • Post category:python


初始化:

可以通过enum_ = Enum(‘class_name’, names,start = 1)来创建,其中names可以是字符串,可以是列表/元组。内部定义为:

def _create_(cls, class_name, names, *, module=None, qualname=None, type=None, start=1):

“””Convenience method to create a new Enum class.

`names` can be:

* A string containing member names, separated either with spaces or

commas. Values are incremented by 1 from `start`.

* An iterable of member names. Values are incremented by 1 from `start`.

* An iterable of (member name, value) pairs.

* A mapping of member name -> value pairs.

“””

metacls = cls.__class__

bases = (cls, ) if type is None else (type, cls)

_, first_enum = cls._get_mixins_(bases)

classdict = metacls.__prepare__(class_name, bases)

# special processing needed for names?

if isinstance(names, str):

names = names.replace(‘,’, ‘ ‘).split()

if isinstance(names, (tuple, list)) and names and isinstance(names[0], str):

original_names, names = names, []

last_values = []

for count, name in enumerate(original_names):

value = first_enum._generate_next_value_(name, start, count, last_values[:])

last_values.append(value)

names.append((name, value))

# Here, names is either an iterable of (name, value) or a mapping.

for item in names:

if isinstance(item, str):

member_name, member_value = item, names[item]

else:

member_name, member_value = item

classdict[member_name] = member_value

enum_class = metacls.__new__(metacls, class_name, bases, classdict)

# TODO: replace the frame hack if a blessed way to know the calling

# module is ever developed

if module is None:

try:

module = sys._getframe(2).f_globals[‘__name__’]

except (AttributeError, ValueError, KeyError) as exc:

pass

if module is None:

_make_class_unpicklable(enum_class)

else:

enum_class.__module__ = module

if qualname is not None:

enum_class.__qualname__ = qualname

return enum_class

通过这样就可以初始化并返回一个枚举类。

关于Enum的元素的使用

通过源码可知:可以通过:enum_(value).vlaue/name,或者sth = enum.name–>sth.name/value,至于为什么,需要查看源码:

class DynamicClassAttribute:

“””Route attribute access on a class to __getattr__.

This is a descriptor, used to define attributes that act differently when

accessed through an instance and through a class. Instance access remains

normal, but access to an attribute through a class will be routed to the

class’s __getattr__ method; this is done by raising AttributeError.

This allows one to have properties active on an instance, and have virtual

attributes on the class with the same name (see Enum for an example).

“””

def __init__(self, fget=None, fset=None, fdel=None, doc=None):

self.fget = fget

self.fset = fset

self.fdel = fdel

# next two lines make DynamicClassAttribute act the same as property

self.__doc__ = doc or fget.__doc__

self.overwrite_doc = doc is None

# support for abstract methods

self.__isabstractmethod__ = bool(getattr(fget, ‘__isabstractmethod__’, False))

def __get__(self, instance, ownerclass=None):

if instance is None:

if self.__isabstractmethod__:

return self

raise AttributeError()

elif self.fget is None:

raise AttributeError(“unreadable attribute”)

return self.fget(instance)

def __set__(self, instance, value):

if self.fset is None:

raise AttributeError(“can’t set attribute”)

self.fset(instance, value)

def __delete__(self, instance):

if self.fdel is None:

raise AttributeError(“can’t delete attribute”)

self.fdel(instance)

def getter(self, fget):

fdoc = fget.__doc__ if self.overwrite_doc else None

result = type(self)(fget, self.fset, self.fdel, fdoc or self.__doc__)

result.overwrite_doc = self.overwrite_doc

return result

def setter(self, fset):

result = type(self)(self.fget, fset, self.fdel, self.__doc__)

result.overwrite_doc = self.overwrite_doc

return result

def deleter(self, fdel):

result = type(self)(self.fget, self.fset, fdel, self.__doc__)

result.overwrite_doc = self.overwrite_doc

return result

需要先实例化才能使用。



版权声明:本文为weixin_39560064原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。