Python Enum 技巧,让代码更简洁、更安全、更易维护
如果你是一名 Python 开发人员,你很可能使用过 enum.Enum 来创建可读性和可维护性代码。
今天发现一个强大的技巧,可以让Enum的境界更进一层,这个技巧不仅能提高可读性,还能以最小的代价增加额外的功能。
在本文中,云朵君和大家一起学习一种高级Enum模式,它能让你的 Python 代码更健壮、更易维护、更高的鲁棒性。
为什么在 Python 中使用Enum?
在我们深入探讨这个技巧之前,让我们先简单了解一下 Enums 为什么有用。
枚举可以帮助你定义一组命名的常量,使你的代码更易读、更不易出错。与使用神奇的数字或硬编码字符串相比,你可以使用枚举来表示具有有意义名称的值。
没有Enum(糟糕的做法):
STATUS_PENDING = "pending"
STATUS_APPROVED = "approved"
STATUS_REJECTED = "rejected"
def process(status):
if status == "approved":
print("Processing approved request")
问题出在哪里?字符串容易出现错别字,而且缺乏结构。
使用Enum(更好的方法):
from enum import Enum
class Status(Enum):
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
def process(status: Status):
if status == Status.APPROVED:
print("Processing approved request")
现在,我们的代码更有条理了,而且还能通过Enum获得类型安全。
Enum技巧:添加额外功能
虽然标准枚举很棒,但它们仍然只是基本常量。如果我们能为每个Enum成员添加额外的元数据或行为呢?
使用 @property和自定义方法
我们可以通过添加属性和方法来增强Enum,从而提供额外的功能。具体方法如下
from enum import Enum
class Status(Enum):
PENDING = "pending"
APPROVED = "approved"
REJECTED = "rejected"
@property
def description(self):
descriptions = {
"pending": "The request is pending approval.",
"approved": "The request has been approved.",
"rejected": "The request was rejected."
}
return descriptions[self.value]
我们不再需要单独管理描述,而是可以直接访问它们:
print(Status.PENDING.description) # Output: The request is pending approval.
print(Status.APPROVED.description) # Output: The request has been approved.
这将使enum更丰富和 self-contained。
Enum高级技巧:映射额外数据
通过存储额外的属性,还可以在Enum中使用类似于 dataclass 的行为。
from enum import Enum
class Status(Enum):
PENDING = ("pending", "")
APPROVED = ("approved", "")
REJECTED = ("rejected", "")
def __init__(self, value, emoji):
self._value_ = value
self.emoji = emoji
@property
def description(self):
descriptions = {
"pending": "The request is pending approval.",
"approved": "The request has been approved.",
"rejected": "The request was rejected."
}
return descriptions[self.value]
# Usage
print(Status.PENDING.emoji) # Output:
print(Status.APPROVED.description) # Output: The request has been approved.
- 将相关数据保存在一起 - 无需外部映射。
- 提高可维护性 - 状态的更改不需要修改代码的多个部分。
- 提高可读性 - 开发人员可以快速查看可用状态及其属性。