切换到数据类
作者: harshil21创建于 2026年6月26日更新于 2026年8月13日
标签🛠 refactor🛠 breaking
细节问题
- 不变性:我们采用的解决方案是自行实现冻结,通过
_frozen属性。数据类还提供了通过frozen=True参数实现的自己的版本。以下是使用该方法的利弊: 1. ➖ IISC,数据类没有一种方法可暂时解冻对象,这意味着需要使用object.__setattr__作为一种工作绕行方法,特别是在测试中。 2. ➖/➕ 在混合使用槽和冻结时出现了几个小问题:https://GitHub.com/Python/cpython/issues/105936,尽管在 Python 3.13 及更高版本中已解决。如果用户在 3.13 以下遇到此问题,我们可能只能要求他们升级,但该问题中的场景不会发生在我们的库中。 3. ➕ 使用数据类方法初始化新类比较快,速度提高了 3-10 倍[^1]。我让 codex 编写了一个 脚本。结果令人惊讶,因为我预期相反。 个人而言,我稍微支持使用数据类 frozen=True 方法,因为它带来了“免费”的性能提升。 2. 等价性比较:数据类还提供了自己的比较方法,使用compare=True,从而消除了我们手动的_id_attrs逻辑的需要。目前我并不认为我们不应该使用他们的方法。唯一的麻烦是如果不想包含用于等价性比较的字段,则需要写入更多的框架。您需要执行field(eq=False)。使用frozen=True,__hash__方法也会为我们处理,并会检查我们希望它检查的属性。 3. repr:数据类也可以为我们做这件事,但既然我们已经有了自己的方法,该方法通过删除 None 值和空容器来定制外观,我们可以继续使用它。 4. slots:以前是 阻碍因素之一,因为我们只支持 3.10+,所以我们不再有这个问题。 5. 由于我们不需要它们,我们应该在所有 TelegramObjects 中全局禁用__match_args__。 6. 一些类常量需要用ClassVar标注,特别是Final类型。 7. 我们应该提到,dataclasses.asdict和dataclasses.asdict都会将对象转换为字典,但我们不需要它们。
内容来源: python-telegram-bot/python-telegram-bot