切换到数据类

作者: harshil21创建于 2026年6月26日更新于 2026年8月13日
标签🛠 refactor🛠 breaking

细节问题

  1. 不变性:我们采用的解决方案是自行实现冻结,通过 _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.asdictdataclasses.asdict 都会将对象转换为字典,但我们不需要它们。

内容来源: python-telegram-bot/python-telegram-bot