数据类型
👍enum 模块
基本示例
from enum import Enum
class TrafficLight(Enum):
RED = 1
YELLOW = 2
GREEN = 3
# YELLOW = 1 #常见错误:将枚举成员的值设置为相同类型
# RED = [255, 0, 0] # 常见错误:错误地将枚举成员的值设置为可变类型
# YELLOW = None # 常见错误:错误地将枚举成员的值设置为None、False、True等
# 使用枚举
light = TrafficLight.RED
# if light == 1 常见错误:错误地使用Enum成员进行比较
if light == TrafficLight.RED:
print("红灯,停车")
elif light == TrafficLight.YELLOW:
print("黄灯,准备")
else:
print("绿灯,通行")
是否使用Enum
取决于你项目的需求和代码的复杂度。你可能觉得不需要它,尤其是在简单的场景下,直接使用字符串或整数常量看似足够。但是,Enum
有以下几个优势:
1. 增加可读性
当你看到Color.RED
时,比直接看到一个1
或'red'
更容易理解。Enum
能让你的代码更具语义化,避免硬编码的常量值。
例如:
status = Status.SUCCESS # 一目了然:状态是成功
相比:
status = 1 # 需要额外判断 1 是什么意义
2. 减少错误
使用Enum
可以避免常见的错误,比如不小心使用了错误的值或者字符串拼写错误。Enum
成员是唯一的,且不可变的,能够防止无意间改变它们的值。
比如,如果你用了Status.SUCCESS = 1
,然后在后续代码中某处错误地设置了Status.SUCCESS = 2
,你会收到警告或报错,而不是默默覆盖,产生潜在的 bug。
3. 类型安全
使用Enum
可以确保变量的值只来自于枚举成员,而不会误用其他类型的值(如普通的数字、字符串等)。这对于大型项目来说 尤其重要,因为它能有效地避免一些奇怪的 bug。
比如:
def set_color(color: Color):
if not isinstance(color, Color):
raise ValueError("Invalid color")
4. 易于扩展和维护
随着项目的扩展,你可能会有更多的常量值需要添加,Enum
让这种扩展变得更清晰、更系统化。你不再需要在多个地方定义相同的常量,所有的常量都集中在一个地方。
比如,随着系统需求变化,你可能需要扩展交通灯的状态:
class TrafficLight(Enum):
RED = 1
YELLOW = 2
GREEN = 3
FLASHING = 4 # 新增状态
5. 集成与协作的优势
在多人开发的团队中,使用Enum
可以提高协作性。它使得每个成员的代码中常量的含义更加清晰,减少误解或重复定义的问题。
6. 可迭代、可比较
Enum
支持迭代、比较等操作,允许你灵活处理。例如,你可以遍历所有的Enum
成员,或者比较它们的顺序。
for state in TrafficLight:
print(state)
typing 模块
typing
模块提供高级类型支持:
from typing import List, Dict, Tuple, Optional, Union
# 容器类型
names: List[str] = ["Alice", "Bob"]
person: Dict[str, Union[str, int]] = {"name": "Alice", "age": 30}
# 可选类型
def get_age(name: str) -> Optional[int]:
if name == "Alice":
return 30
return None
# 类型别名
UserId = int
user_id: UserId = 1001
泛型 (Generic)
创建可复用的类型安全容器:
from typing import TypeVar, Generic, List
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self) -> None:
self._items: List[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
# 使用
int_stack: Stack[int] = Stack()
int_stack.push(42)
Literal 字面量类型
限制值只能是特定的字面量:
from typing import Literal
def set_mode(mode: Literal["read", "write", "append"]) -> None:
print(f"Mode set to: {mode}")
set_mode("read") # 正确
set_mode("delete") # 类型检查器会报错
# 多种类型的字面量
def process_flag(flag: Literal[True, False, 0, 1]) -> None:
pass