在阅读了这个内容丰富(尽管有些争论)的问题之后,我想知道您使用 Python 编写大型项目的经验。随着项目变大,事情是否变得难以管理?这种担忧是让我对 Java 依恋的一件事。因此,我对大型项目的 Java 和 Python 的可维护性和可扩展性的知情比较特别感兴趣。
8 回答
我从事一个用 Python 完成的大型商业产品。我粗略估计了 5000 个文件 x 500 行。这大约是 250 万行 Python。请注意,这个项目的复杂性可能相当于其他语言的 1000 万多行代码。我没有听到任何一位工程师/架构师/经理抱怨 Python 代码不可维护。根据我从错误跟踪器中看到的情况,我没有看到任何可以通过静态类型检查避免的系统性问题。事实上,几乎没有错误使用对象类型产生的错误。
我认为这是一个非常好的学术主题,可以实证研究为什么基于静态类的语言似乎不像人们想象的那么重要。
关于可扩展性。我们刚刚在我们的产品中的数据库 1 之上添加了一个数据库 2,它们都是非 SQL。没有与类型检查相关的问题。首先,我们设计了一个足够灵活的 API,可以预测不同的底层实现。我认为动态语言在这方面是一种帮助而不是阻碍。当我们继续测试和修复错误时,我们正在研究使用任何语言的人都必须面对的那种错误。例如,内存使用问题、一致性和参照完整性问题、错误处理问题。我认为静态类型检查对这些挑战没有多大帮助。另一方面,我们从动态语言中受益匪浅,因为我们能够在运行中或在简单的补丁之后注入代码。
可以肯定地说,我们 100 多名工程师中的大多数人都乐于使用 Python 并富有成效。对于我们来说,使用静态类型语言在相同的时间内以相同的质量构建相同的产品可能是不可想象的。
根据我的经验,静态类型的语言可能很难维护。例如,假设您有一个实用函数,它接受自定义类作为参数。如果以后你采用新的命名约定,那么这个类的名称将不得不改变,那么你所有的实用函数也必须改变。在像 python 这样的语言中,只要类实现相同的方法并不重要。
就我个人而言,我鄙视一种妨碍我的语言。表达想法的速度就是价值,这是 Python 相对于 Java 的优势。
python 中没有良好测试覆盖率的大型代码库可能是一个问题。但这只是图像的一部分。一切都是关于人和合适的方法来完成这项工作。
没有
- 源代码控制
- 错误跟踪
- 单元测试
- 承诺团队
你可能会用任何一种语言失败。
尝试在具有大量 IoC 或其他设计模式的大型动态类型框架中追溯明显格式错误的对象的来源,其中无法直接在堆栈中跟踪对象。
现在尝试用静态类型的语言来做这件事。
除非对象的类型记录在使用站点附近(例如,通过类型注释,a-la Python 的类型安全库)或堆栈上的某个位置,否则几乎不可能推断出它的来源。我根据经验发言,曾尝试调试 BuildBot 框架的某些部分。它涉及通过框架搜索大量原始文本,甚至使用 PyDev、Komodo 和 Wingware 等花哨的 IDE。
我不怀疑对动态语言施加一些类型约束是可能的,但是缺乏任何标准化似乎是任何尝试调试大型现有框架的一部分的人的障碍。
编辑:自 2014 年以来,Guido 添加了 PEP484、MyPy 和打字模块。这使我在维护大型项目方面的经验好得多。
I remember the days before and after the innovation of IntelliJ IDEA. There are huge differences. Before, static typing was only for compilation, development basically treats source code as text files. After, source code is structured information, many development tasks are must easier, thanks to static typing.
However, it's not like the old days were living hell. We took it as is, do whatever necessary, use the tools available to date, get the system built, satisfaction. There weren't too many unhappy memories. That's probably what dynamic typing programmers feel now. It's not that bad.
Of course, I'll never go back to the old days. If I'm forbidden to use such an IDE, I guess I'll give us programming all together.
根据我的经验,可维护性取决于低耦合、良好的文档、良好的开发过程和出色的测试。静态类型与这些几乎没有关系。
Java 在编译时捕获的错误只是可能发生的错误的一小部分。它们也几乎总是最容易通过测试检测到的;如果您正在测试您的代码是否产生正确的答案,那么您绝对不会错过对错误类的对象调用方法!在这方面,您可能会争辩说 Python 实际上更适合确保质量。通过强迫您至少进行一些测试以确保您的代码没有简单的拼写错误,它可以确保您实际上至少进行了一些测试。
事实上,Java 甚至不是一个很好的语言示例,它具有强大的静态检查以捕获大量错误。尝试在 Haskell 或 Mercury 中编程以了解我的意思,或者更好地尝试在 Scala 中编程并与 Java 库交互;当您将使用 Scala 库的普通惯用 Scala 代码与必须处理 Java 库的代码进行比较时,编译器能够为您保证多少“正确性”的差异是惊人的(我实际上已经这样做了,因为我编写了一个位在 Android 上的 Scala 中)。
尽管 Java 的静态错误检测与 Scala 等语言相比存在缺陷,但您在大型代码库中编写良好的可维护代码的能力由许多开发人员长期研究,这取决于Python 程序员使用完全相同的技术来做同样的事情尽管与 Java 相比,Python 的静态错误检测存在缺点,但它们的大型代码库中的东西。
我在很多项目中都使用过 Python,从几百行到几千行不等。动态类型非常节省时间,它使像多态这样的 OO 概念更容易使用。类型系统不会使项目无法维护。如果您无法想象,请尝试用 Python 编写一些东西,看看它们是如何进行的。
我在一家使用 python 作为主要语言的大数据初创公司工作。我的项目大约是 30k 行 python。根据我的经验,如果您的团队采用良好的编程实践,例如 fox 示例、添加类型提示和广泛的单元测试,它可能不会那么影响可维护性。因为如果有类型提示,Pycharm 可以自动检测类型某些类型错误。
真正的问题是: 1. 性能,这可能与可维护性无关,但它是一个问题。2. 并非您处理的每个 python 代码库都写得很好。因为python很容易学习和编码。一些没有受过基本 CS 培训的人会开发一个无法维护的 python 项目。我工作了一个 python 项目,它有很多文件,每个文件都有几千行,没有类型提示。那家伙不知道OOP。他基本上以编写 C 的方式编写 python。他只是利用了一些 python 语言特性,但完全是命令式编程。编写好的 Python 项目确实依赖于训练有素的工程师。如果你不能聘请足够好的工程师,最好依靠工具本身。3.在python大数据公司,产品经理和一些非技术人员不关心数据类型的一致性。那些人会设计一个不是类型安全的数据产品。例如,在 Json 中,如果一个字段通常是 str,但是当它为空时,有些人会将其设为 null。这将在运行时失败。