在我们谈论 Python 之前,让我们先谈谈“密封”:
我也听说过 .Net 密封/Java final/C++ 完全非虚拟类的优势在于性能。我是从 Microsoft 的 .Net 开发人员那里听说的,所以也许是真的。如果您正在构建一个重度使用、高性能敏感的应用程序或框架,您可能希望将少数类密封在或接近真实的、已分析的瓶颈处。特别是您在自己的代码中使用的类。
对于大多数软件应用程序,将其他团队作为框架/库/API 的一部分使用的类密封起来有点……奇怪。
主要是因为无论如何,任何密封类都有一个简单的解决方法。
我教授“基本测试驱动开发”课程,在这三种语言中,我建议这种密封类的使用者将其包装在具有完全相同方法签名的委托代理中,但它们是可覆盖的(虚拟),因此开发人员可以为这些缓慢的、不确定的或引起副作用的外部依赖项创建测试替身。
[警告:下面的蛇皮意为幽默。请激活您的幽默感子程序阅读。我确实意识到有些情况下需要密封/最终。]
代理(不是测试代码)有效地解封(重新虚拟化)类,导致 v-table 查找和可能效率较低的代码(除非编译器优化器足以内联委托)。优点是您可以有效地测试自己的代码,每月为生活、呼吸人类节省数周的调试时间(与为您的应用程序节省几百万微秒相比)...... [免责声明:这只是一个 WAG。是的,我知道,您的应用程序很特别。;-]
所以,我的建议:(1) 相信你的编译器的优化器,(2) 停止创建你构建的不必要的密封/最终/非虚拟类,以便 (a) 在一个不太可能的地方维持每一微秒的性能无论如何你的瓶颈(键盘,互联网......),或者(b)对你团队的“初级开发人员”产生某种误导的编译时间约束(是的......我也看到了)。
哦,(3)先写测试。;-)
好的,是的,也总是存在链接时模拟(例如 TypeMock)。你得到了我。来吧,封你的课。什么。
回到 Python:存在 hack 而不是关键字这一事实可能反映了 Python 的纯虚拟特性。这不是“自然的”。
顺便说一句,我来这个问题是因为我有完全相同的问题。在我极具挑战性和现实性的遗留代码实验室的 Python 端口上工作,我想知道 Python 是否有像 seal 或 final 这样可恶的关键字(我在 Java、C# 和 C++ 课程中将它们用作单元测试的挑战)。显然它没有。现在我必须为未经测试的 Python 代码找到同样具有挑战性的东西。嗯……