python: 使用类而非字典的开销?

6 投票
6 回答
3206 浏览
提问于 2025-04-15 13:39

首先,我想说明我了解面向对象编程的概念,也知道字典和类之间的区别。我的问题是关于在这种情况下,设计上什么更合理:

我正在用Python设计一个网页应用,需要表示一个类似书籍的对象。书籍有章节,章节有标题和内容。为了简单起见,我们假设内容是纯文本。

我的问题是,我应该用类来表示书和章节,还是用字典?我知道用book.chapter看起来比book['chapter']更整洁,如果将来我需要添加一些方法,把它们放在书的类里可能更合适。不过,我想知道使用类是否会比用字典存储信息有额外的负担?

如果我不想每次都从数据库实例化一个书籍对象,并把它存储为pickle格式,我就得担心如果我添加或删除类中的数据成员,之前的书籍对象会不兼容。我觉得用字典处理这个问题会更简单。有没有什么建议,关于在什么情况下使用字典而不是类更合适?

6 个回答

5

你总结得很好,关于权衡的部分。很多人对性能的担忧来得太早了。与其重复一些常见的建议,不如去网上搜索一下“Knuth 早期优化”。实际上,对于那些结构已知的对象,使用基于类的对象会让你更开心,而不是用字典。

另外,你不想每次读取数据库中的实例数据时都创建对象,这其实是对程序设计中某些部分的错误关注。根据数据属性创建你类的实例其实花费的时间非常少,而通过方法添加功能的便利性,绝对值得你接受一点额外的复杂性。

用字典和固定的下标来引用数据对象的元素,我觉得这有点不太对。你实际上是在模仿Python的命名空间机制,还创建了很多不必要的字符串常量(这些常量不一定会被解释器合并)。如果你真的关心速度,为什么不使用列表,并用符号常量来表示字段名呢?答案是:这样扭曲你的代码为了可能微不足道的执行速度提升是错误的,因为在99%的情况下(这个数字我随便说的),你根本不会注意到,因为应用程序并不受CPU限制。

写程序的时候,尽量用你最简单的方法。如果它能正常工作且运行速度足够快,那就继续进行下一个任务吧。

8

几点想法:

  1. 如果你一开始用字典来存数据,将来想换成自定义的类也很简单,只要这个类能实现映射协议(或者是字典的子类)。所以,从字典开始是个不错的选择。

  2. 你可以定义自定义的Python对象来使用 __slots__,这样如果你有很多对象的话,会更快且更节省内存。

  3. 如果你使用自定义的Python对象,将来想用C语言写的对象替换它会更容易。(我自己没试过,但我觉得从C语言继承字典可能会比较复杂。)

10

这件事在你的应用程序中几乎不可能是性能瓶颈,所以担心性能可能是浪费时间。不过,如果它真的是瓶颈,或者你有时间的话,可以考虑使用一个namedtuple。它把元组(tuple)的不可变性和低内存占用,跟类属性的好语法结合在了一起。

撰写回答