这篇文章将为大家详细讲解有关Python中的枚举类型是什么,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

在Python中,枚举和我们在对象中定义的类变量时一样的,每一个类变量就是一个枚举项,访问枚举项的方式为:类名加上类变量。

虽然这样是可以解决问题的,但是并不严谨,也不怎么安全,比如:

1、枚举类中,不应该存在key相同的枚举项(类变量)

2、不允许在类外直接修改枚举项的值

下面来看看如何实现枚举类型:

importoperatorclassEnumValue(object):def__init__(self,parent_name,name,value):self._parent_name=parent_nameself._name=nameself._value=valuedef_parents_equal(self,other):return(hasattr(other,'_parent_name')andself._parent_name==other._parent_name)def_check_parents_equal(self,other):ifnotself._parents_equal(other):raiseTypeError('Thisoperationisvalidonlyforenumvaluesofthesametype')def__eq__(self,other):returnself._parents_equal(other)andself._value==other._valuedef__ne__(self,other):returnnotself.__eq__(other)def__lt__(self,other):self._check_parents_equal(other)returnself._value<other._valuedef__le__(self,other):self._check_parents_equal(other)returnself._value<=other._valuedef__gt__(self,other):self._check_parents_equal(other)returnself._value>other._valuedef__ge__(self,other):self._check_parents_equal(other)returnself._value>=other._valuedef__hash__(self):returnhash(self._parent_name+str(self._value))def__repr__(self):return'{}({!r},{!r},{!r})'.format(self.__class__.__name__,self._parent_name,self._name,self._value)def__int__(self):returnint(self._value)def__str__(self):returnstr(self._name)classEnumMetaclass(type):def__new__(cls,name,bases,dct):uppercased=dict((k.upper(),v)fork,vindct.items())new_dct=dict(name=name,_enums_by_str=dict((k,EnumValue(name,k,v))fork,vinuppercased.items()),_enums_by_int=dict((v,EnumValue(name,k,v))fork,vinuppercased.items()),)returnsuper(EnumMetaclass,cls).__new__(cls,name,bases,new_dct)def__getattr__(cls,name):try:returncls.__getitem__(name)exceptKeyError:raiseAttributeErrordef__getitem__(cls,name):try:name=name.upper()exceptAttributeError:passtry:returncls._enums_by_str[name]exceptKeyError:returncls._enums_by_int[name]def__repr__(cls):return'{}({!r},{})'.format(cls.__class__.__name__,cls.name,','.join('{}={}'.format(v._name,v._value)forvinsorted(cls._enums_by_str.values())))defvalues(cls):returnsorted(cls._enums_by_str.values())def_values_comparison(cls,item,comparison_operator):"""Returnalistofvaluessuchthatcomparison_operator(value,item)isTrue."""returnsorted([vforvincls._enums_by_str.values()ifcomparison_operator(v,item)])defvalues_lt(cls,item):returncls._values_comparison(item,operator.lt)defvalues_le(cls,item):returncls._values_comparison(item,operator.le)defvalues_gt(cls,item):returncls._values_comparison(item,operator.gt)defvalues_ge(cls,item):returncls._values_comparison(item,operator.ge)defvalues_ne(cls,item):returncls._values_comparison(item,operator.ne)defenum_factory(name,**kwargs):returnEnumMetaclass(name,(),kwargs)

Python中枚举的测试:

importunittestclassEnumTestCase(unittest.TestCase):deftest_repr(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(repr(ProfileAction),"EnumMetaclass('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)")deftest_value_repr(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(repr(ProfileAction.VIEW),"EnumValue('ProfileAction','VIEW',1)")deftest_attribute_error(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)withself.assertRaises(AttributeError):ProfileAction.ASDFASDFdeftest_cast_to_str(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(str(ProfileAction.VIEW),'VIEW')deftest_cast_to_int(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(int(ProfileAction.VIEW),1)deftest_access_by_str(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction['VIEW'],ProfileAction.VIEW)deftest_access_by_int(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction[1],ProfileAction.VIEW)deftest_equality(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction.VIEW,ProfileAction.VIEW)self.assertEqual(ProfileAction['VIEW'],ProfileAction.VIEW)self.assertEqual(ProfileAction[1],ProfileAction.VIEW)deftest_inequality(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertNotEqual(ProfileAction.VIEW,ProfileAction.EDIT_OWN)self.assertNotEqual(ProfileAction['VIEW'],ProfileAction.EDIT_OWN)self.assertNotEqual(ProfileAction[1],ProfileAction.EDIT_OWN)DashboardAction=enum_factory('DashboardAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertNotEqual(ProfileAction.VIEW,DashboardAction.VIEW)deftest_invalid_comparison(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)DashboardAction=enum_factory('DashboardAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)withself.assertRaises(TypeError)ascm:ProfileAction.VIEW<DashboardAction.EDIT_OWNself.assertEqual(str(cm.exception),'Thisoperationisvalidonlyforenumvaluesofthesametype')deftest_values(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction.values(),[EnumValue('ProfileAction','VIEW',1),EnumValue('ProfileAction','EDIT_OWN',2),EnumValue('ProfileAction','EDIT_PUBLIC',3),EnumValue('ProfileAction','EDIT_FULL',4),])deftest_values_lt(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction.values_lt(ProfileAction.EDIT_PUBLIC),[EnumValue('ProfileAction','VIEW',1),EnumValue('ProfileAction','EDIT_OWN',2),])deftest_values_le(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction.values_le(ProfileAction.EDIT_PUBLIC),[EnumValue('ProfileAction','VIEW',1),EnumValue('ProfileAction','EDIT_OWN',2),EnumValue('ProfileAction','EDIT_PUBLIC',3),])deftest_values_gt(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction.values_gt(ProfileAction.EDIT_PUBLIC),[EnumValue('ProfileAction','EDIT_FULL',4),])deftest_values_ge(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction.values_ge(ProfileAction.EDIT_PUBLIC),[EnumValue('ProfileAction','EDIT_PUBLIC',3),EnumValue('ProfileAction','EDIT_FULL',4),])deftest_values_ne(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)self.assertEqual(ProfileAction.values_ne(ProfileAction.EDIT_PUBLIC),[EnumValue('ProfileAction','VIEW',1),EnumValue('ProfileAction','EDIT_OWN',2),EnumValue('ProfileAction','EDIT_FULL',4),])deftest_intersection_with_same_type(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)set_a=set([ProfileAction.VIEW,ProfileAction.EDIT_OWN])set_b=set([ProfileAction.VIEW,ProfileAction.EDIT_PUBLIC])self.assertEqual(set_a&set_b,set([ProfileAction.VIEW]))deftest_intersection_with_different_types(self):ProfileAction=enum_factory('ProfileAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)DashboardAction=enum_factory('DashboardAction',VIEW=1,EDIT_OWN=2,EDIT_PUBLIC=3,EDIT_FULL=4)set_a=set([ProfileAction.VIEW,ProfileAction.EDIT_OWN])set_b=set([DashboardAction.VIEW,DashboardAction.EDIT_PUBLIC])self.assertEqual(set_a&set_b,set([]))

关于Python中的枚举类型是什么就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。