什么是enum,为什么需要它?

枚举类型,也称为enum,是一种数据类型,由一组命名值组成。这些可枚举的命名值充当计算机语言中的常量。例如,COLOR枚举可以包括诸如RED, GREEN, BLUE等命名值。这些命名值都是大写,以区别于变量。

为什么要使用枚举呢?可以想像这样一种情景:需要在网站中将用户的性别限制为MALE, FEMALE和N/A。当然,字符串列表也可以胜任,如user.gender='MALE',user.gender='FEMALE'。但使用字符串作为性别属性值显得不够强壮,程序员在使用过程中容易出错或者受到恶意攻击。程序员很容易将'MALE'误拼写为'ALE',或者将'FEMALE'误拼写为'EMAIL',代码虽然仍可以运行,但会产生严重结果。攻击者可能会仔细构建垃圾字符串值,导致系统崩溃或获取根访问权限。如果使用枚举,则可将user.gender属性的值限制在有限的值列表中,这样前面提到的问题就不会出现了。

Python中枚举的简单实现方式

在Python中,内置函数type可以接受1个或3个参数,当向type传递1个参数时,它会返回一个对象类型;当传递3个参数时,如type(name,bases,dict),它会返回一个新的对象类型。这是class语句的一种动态形式。第1个参数name字符串是类名;第2个参数bases元组则指定了新类型的基类;第3个参数dict是命名空间,包含了对类体的定义。

使用type,可以通过以下的方式构建一个enum:


现在Color和Gender是类,其作用与enum类似,可以用下面方式使用它们:


当传递无效的字符串时,User构造器会拒绝。

Python中实现枚举的复杂方式

尽管上面实现enum的方式简单,但它要求显式地为每一个命名值指定一个值。例如在enum(MALE='male', FEMALE='female', N_A='n/a')中,MALE是名称,'male'是对应于名称的值。由于大多数时候,只通过名称来使用enum,因此可以实现一个enum,让它通过以下方式自动赋值:


使用zip和range,代码会为args中的每一个名称赋一个整数值。

Python中使用枚举的技巧与建议

enum有助于为属性限制可选的值,这在实际编程中非常有用。在处理数据库时,enum在Python和数据库管理系统中应用是等同的,这样就可以避免很多难以发现的bug。

使用enum可以有效地保护系统,使其杜绝恶意输入。在系统接受用户输入前,一定要检查输入的值。