一、开篇:告别"魔术数字"
你的代码里有多少这样的"魔术数字"?
# ❌ 魔术数字——三个月后谁都看不懂
if status == 1:
print("处理中")
elif status == 2:
print("已完成")
elif status == 0:
print("已取消")
# ✅ 枚举——意图一目了然
from enum import enum
class orderstatus(enum):
cancelled = 0
processing = 1
completed = 2
if status == orderstatus.processing:
print("处理中")
💡 枚举(enum)给一组相关的常量赋予有意义的名字。它提高代码可读性、防止拼写错误、约束取值范围——是消除"魔术数字"的利器。
二、基本使用
2.1 创建和访问枚举
from enum import enum
class color(enum):
red = 1
green = 2
blue = 3
# 三种访问方式
print(color.red) # color.red
print(color["red"]) # color.red —— 通过名字
print(color(1)) # color.red —— 通过值
# 枚举成员的属性
print(color.red.name) # "red" —— 名字
print(color.red.value) # 1 —— 值
# 比较
print(color.red == color.red) # true
print(color.red == color.blue) # false
print(color.red is color.red) # true —— 同一成员是单例
# print(color.red > color.green) # typeerror —— 不支持大小比较(除非intenum)
# 迭代
for color in color:
print(f" {color.name} = {color.value}")
2.2 auto()自动赋值
from enum import enum, auto
class status(enum):
pending = auto() # 1
approved = auto() # 2
rejected = auto() # 3
cancelled = auto() # 4
print([(s.name, s.value) for s in status])
# [('pending', 1), ('approved', 2), ('rejected', 3), ('cancelled', 4)]
# 自定义auto行为
class myauto(enum):
def _generate_next_value_(name, start, count, last_values):
"""自定义auto生成的value"""
return name.lower() # 用名字的小写作为值
class configkey(myauto):
host = auto() # "host"
port = auto() # "port"
debug = auto() # "debug"
print([(k.name, k.value) for k in configkey])
三、枚举的变体
3.1 intenum——可与整数比较
from enum import intenum
class priority(intenum):
low = 1
medium = 3
high = 5
urgent = 10
# intenum可以当作整数使用
print(priority.high == 5) # true
print(priority.high > priority.low) # true —— 支持大小比较
print(priority.high + 1) # 6
# 但和普通enum相比,失去了类型安全性
# priority.high == 5是true——可能不是你想要的
3.2 flag——位标志
from enum import flag, auto
class permission(flag):
none = 0
read = auto() # 1
write = auto() # 2
delete = auto() # 4
admin = read | write | delete # 7
# 组合权限
user_perms = permission.read | permission.write # 3
print(user_perms) # permission.read|write
print(permission.read in user_perms) # true
print(permission.delete in user_perms) # false
# 赋予权限
user_perms |= permission.delete
print(permission.admin in user_perms) # true
# 实战:文件权限系统
def can_access(required, user_permission):
"""检查用户是否有足够的权限"""
return required in user_permission
print(can_access(permission.read, permission.read | permission.write)) # true
print(can_access(permission.delete, permission.read | permission.write)) # false
四、实战案例
4.1 api状态码
from enum import intenum
class httpstatus(intenum):
"""http状态码枚举"""
ok = 200
created = 201
bad_request = 400
unauthorized = 401
forbidden = 403
not_found = 404
internal_error = 500
def is_success(self):
return 200 <= self.value < 300
def is_client_error(self):
return 400 <= self.value < 500
def handle_response(status_code, body):
"""处理http响应"""
status = httpstatus(status_code)
if status.is_success():
print(f"✓ {status.name}: {body}")
elif status.is_client_error():
print(f"✗ {status.name}: 客户端错误")
else:
print(f"⚠ {status.name}: 服务器错误")
handle_response(200, "操作成功")
handle_response(404, none)
4.2 配置选项
from enum import enum
class loglevel(enum):
debug = 10
info = 20
warning = 30
error = 40
def __ge__(self, other):
"""支持 >= 比较"""
if self.__class__ is other.__class__:
return self.value >= other.value
return notimplemented
class logconfig:
current_level = loglevel.info
@classmethod
def set_level(cls, level):
if not isinstance(level, loglevel):
raise typeerror(f"请使用loglevel枚举,而不是 {type(level)}")
cls.current_level = level
@classmethod
def should_log(cls, level):
return level >= cls.current_level
# 使用——类型安全,不会传错
logconfig.set_level(loglevel.debug)
print(logconfig.should_log(loglevel.info)) # true
五、总结
枚举让一组相关的常量有了类型和名字。它是消除"魔术数字"和提高代码可读性的标准方式。
💡 选型指南:
| 类型 | 用途 | 特点 |
|---|---|---|
| enum | 通用枚举 | 类型安全,不可与整型混用 |
| intenum | 兼容整数的枚举 | 可与整数比较、运算 |
| flag | 位标志 | 支持位运算组合 |
| auto() | 自动赋值 | 不关心具体值时使用 |
✅ 最佳实践:枚举名全大写(pascalcase类名,upper_case成员名)。当你发现代码中有0, 1, 2这样的状态码时——就用枚举。
到此这篇关于python内置模块enum枚举类型的创建使用小结的文章就介绍到这了,更多相关python enum枚举类型内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论