Python与C#/.NET -- 在开发大型网络应用时有哪些关键差异需要考虑?
我们公司现在主要在用一个基于 SQL Server 2005/2008 的网页应用,后端是 Java 模型和控制器,前端是用 ColdFusion 做的视图。我们决定换一个更新的框架,经过内部探索和小项目的尝试,我们把选择缩小到 Python 和 C#/.NET 之间。
首先,我想说的是我知道这两种技术都能很好地工作,我想了解它们之间的主要区别(以及各自的优缺点)。这两种语言有很多相似之处,也有不少不同之处——我想听听你们对它们关键差异的看法。
我想了解的一个例子:
虽然用 Python 似乎可以用更少的代码做更多的事情,发挥更大的创造力,但因为 .NET 更加结构化,所以可能更容易理解和修改别人写的代码。
一些可能有用的额外信息:
我们的工程团队大约有 20 个人,通常分成 5-7 人的小组,成员经常轮换。我们在处理别人写的代码的同时,也会写新代码。
如果选择 Python,我们会使用 Django 框架;如果选择 .NET,我们会用 MVC2。我们的服务器是运行在 Windows 上的 IIS 服务器。
我们喜欢 ColdFusion 的一些地方,比如它处理查询非常简单,而且我们可以“热部署”修复程序到我们的网页服务器上,而不需要重启服务器或打扰正在使用它的人。
我看过一些关于这两种语言的 X 对 Y 的讨论,觉得很有帮助,但我想直接把 Python 和 .NET 放在一起比较。
4 个回答
我还想说,在做出这样的决定之前,我们必须比较运行时间,而不仅仅是看语言的特性。Python是通过CPython解释器运行的,而C#则是在它的默认实现中运行在CLR上。
在任何大型项目中,多任务处理是非常重要的;.NET可以通过线程轻松处理这个问题……而且它还可以利用IIS(ASP.NET)中的工作进程。CPython由于有全局解释器锁(GIL),并不提供真正的线程能力……每个线程在执行任何代码之前都必须获取这个锁,要实现真正的多任务处理,你必须使用多个进程。
当我们在IIS上托管ASP.NET应用程序时,即使是在单个工作进程中,ASP.NET仍然可以利用线程在不同的核心上同时处理多个网页请求,而CPython则依赖多个工作进程在不同的核心上实现并行计算。
这一切都引出了一个大问题,我们该如何在Windows上托管Python/Django应用程序。我们都知道,在Windows上创建进程的成本远高于Linux。因此,理想情况下,托管Python/Django应用程序的最佳环境是Linux,而不是Windows。
如果你选择Python,开发和托管Python的合适环境就是Linux……如果你像我一样来自Windows,选择Python也会让你面临学习Linux的新挑战……不过这些天学习Linux并不是很难……
我在Quora上写了一篇很详细的回答,关于这个问题:Python和C#有什么区别?
简单来说
这个回答内容很丰富,但(希望)也很全面。我在C#和.NET上编程快10年了,所以我对它非常了解。而我在Quora上用Python编程大约7个月,所以我希望我对它也有一定了解。
在以下方面,Python更胜一筹:学习简单、跨平台开发、开源库的可用性。
在以下方面,C#更胜一筹:标准库、语言特性、开发过程和工具、性能、语言演变速度。
大致相当:语法(Python在可读性上更好,C#的语法更一致)、接受度。
“.NET”并不是一种编程语言。可能你在比较的是Python和C#,或者是Python/Django和C#/ASP.NET(你也可以选择其他的“网页开发”方案;Python和“.NET”都有很多不同的解决方案,直接选择Django或MVC2可能会限制你更好的选择)。作为Python和“.NET”的对比,有一个叫IronPython的东西(就是在“.NET”环境下使用Python)。
我会考虑开发者对某种语言的舒适度,如果在Python和“.NET”中都差不多,那我会考虑开发的时间,选择能缩短开发时间的语言或“网页开发”方案(这不一定要受之前的限制)。
虽然单元测试和集成测试对任何[较大]项目都是必须的,但我发现静态类型语言(比如C#/F#)可以大大减少与类型相关的“低级错误”。
让我们打开思路 :-)
编辑以回应评论:
那么你就是在比较语言了。
在这种情况下,C#是一种非常无聊的命令式静态类型语言,采用单继承/接口类的面向对象(OO)设计(但比Java多了一些有趣的特性,Java就显得有点过时)。这和Python的面向对象基本是一样的,除了静态和动态的区别,这两种语言都是强类型的(虽然机制不同,但最终结果在语言的范围内是相似的)。实际上,Python有多重继承,但在Python中似乎不太被接受,使用'lambda'关键字也是如此,而且由于Python是动态类型的,所以在编译时无法确定接口/类型的约定(不过有一些模块试图提供这种支持)。
如果你能学会/了解Python,那么你也能学会/了解C#。这并不是一种范式的转变。只是一些关键字不同,括号的位置不同,需要明确你指的是什么类型,基础库也不同……环境也不同(你需要花点功夫才能在VS中使用REPL,但这是可以做到的)。开发者如何喜欢/学习/使用它又是另一个话题。虽然我之前称C#为命令式语言,但看到它增加了一些“类似函数式”的特性,比如LINQ/IEnumerable扩展和闭包(不需要委托),还是挺不错的,即使基本的C#语法非常过程化——这和Python很像(for表达式、嵌套函数、语句/表达式的划分)。
虽然新的'dynamic'确实模糊了界限(它很少有好的使用场景——大多数情况下是在C#的早期版本中不得不依赖反射的地方——这并不完全正确,但要点是它通常是“错误的选择”,除非在少数情况下它恰好是“最佳/唯一的选择”),但'var'并不是。也就是说,'var'变量的类型在编译时是已知的,与动态类型无关;这完全是类型推断。一些语言,比如F#/SML和Haskell,拥有更强大的类型推断,省去了“那些丑陋的类型声明”的需要(尽管明确标注允许的类型或类型集合可以让意图更清晰),同时保持静态类型。
就我个人而言,不考虑其他因素,我会选择静态类型语言。我并不是说C#(我绝对不说Java!),但静态类型语言可以将类型错误提前,并要求明确的合同(这对我来说是个很大的优势)。虽然你会错过一些有趣的动态特性,但几乎总有更好的方法在目标语言中执行相同的操作——你只需要用那种语言的思维方式去思考,使用螺丝刀拧螺丝,用锤子钉钉子。例如,不要指望把依赖于local()或global()的Python代码直接带入C#。
在“缺点”方面,大多数静态类型语言(这里指C#)需要先编译(但这并不算太糟,因为它能生成漂亮的程序集),而像“REPL”这样的工具并不被视为一等公民(在F#/VS2010中是的)。此外,如果你有一个对Python/C#至关重要的库(而在另一种语言中没有),这可能会成为选择一种语言而非另一种语言的决定性因素。