Python 3.7中如何限制dataclass的action字段取值为"bla"和"foo"?
限制Dataclass字段取值的几种合理实现方式
嘿,这个需求挺常见的,针对Python 3.7里的Action dataclass,要把action字段限制为"bla"和"foo",我给你分享几个靠谱的实现方法:
方法1:使用枚举(Enum)—— 最规范的方案
直接把可选值定义成枚举类型,从根源上约束字段的取值,既能避免拼写错误,又能让代码可读性更强。
from dataclasses import dataclass from enum import Enum class ActionType(Enum): BLA = "bla" FOO = "foo" @dataclass class Action: action: ActionType
使用的时候直接传枚举成员就行:
# 合法 action1 = Action(ActionType.BLA) # 非法,会直接报错(类型不匹配) action2 = Action("bar")
如果需要获取原始字符串,直接用action1.action.value就能拿到"bla"。
方法2:用__post_init__做初始化校验
要是不想引入枚举,在dataclass的初始化后钩子函数里做校验也是个简单直接的办法,初始化时如果传入非法值会立刻抛出异常:
from dataclasses import dataclass @dataclass class Action: action: str def __post_init__(self): allowed_actions = {"bla", "foo"} if self.action not in allowed_actions: raise ValueError(f"action必须是{allowed_actions}中的一个,你传入的是{self.action}")
这样创建实例时:
# 合法 action1 = Action("bla") # 非法,抛出ValueError action2 = Action("bar")
不过要注意,这个方法只在初始化时校验,如果之后直接修改action字段的值(比如action1.action = "bar"),就不会触发校验了。
方法3:用@property封装字段——支持后续修改校验
如果需要在后续修改action字段时也保持校验,那就用属性封装的方式:
from dataclasses import dataclass @dataclass class Action: _action: str # 私有字段存实际值 @property def action(self): return self._action @action.setter def action(self, value): allowed_actions = {"bla", "foo"} if value not in allowed_actions: raise ValueError(f"action必须是{allowed_actions}中的一个,你传入的是{value}") self._action = value
使用的时候:
# 合法 action1 = Action("bla") # 合法修改 action1.action = "foo" # 非法修改,抛出ValueError action1.action = "bar"
总结一下
- 优先选枚举方案:类型安全、代码清晰,适合取值固定且明确的场景;
- 简单需求用**
__post_init__**:代码改动最小,只做初始化校验; - 需要后续修改校验用**
@property**:灵活性更强,能覆盖字段的整个生命周期。
内容的提问来源于stack exchange,提问作者Christian Sauer
相关产品推荐
相关产品推荐

