4008-953622
当前位置: 主页 > 我要项目 > 在大型项目上Python 是个烂语言吗?
在大型项目上Python 是个烂语言吗? 发布时间:2020-01-09

  最近在pongba的google groups看到一个较火的讨论:python是个烂语言。 比较客观的关于python的优点和缺点是什么呢。 这些看法: “ 可以很快的写点简单的东西出来。 但python代码一多开发效率就指数下降 一般的小项目, 代码超过 1000 行写 python 就已经是虐心了 代码超过 10w 以后你就别想用 python 开发了。 python 缺乏真正的开发工具 语法错误都在…

  前YouTuber来讲讲YouTube的故事吧。话说我们YouTuber跟Instagram的朋友吃饭,都要事先约定不谈Python,不然YouTuber分分钟变祥林嫂。不过再怎么吐嘈,YouTube不管从历史,代码量,码农数量,还是支撑的业务规模看,都是一个成功的大型Python Web项目 —— 至少曾经是,为什么是曾经,请一定要看到最后。

  YouTube从一开始就是一个典型的Python + MySQL项目。代码随着业务发展自然生长,在很多年前代码量就以百万计了。这时候的主要工程实践就是一些老生常谈:接口文档,单元测试和集成测试,严格的code review, 还是能维持feature开发;性能上前面一个高度优化的模板引擎 (fire) 后面一个 DB Proxy (vitess.io/) 就撑起了巨大的流量。Google的代码管理、构建系统和持续集成系统确实是好,serving infrastructure也够强悍,这些底子打得好是这个项目不用很多tricks都能撑到这么大的重要原因。

  但此时软件复杂性的问题已经非常明显,在这个规模上YouTube居然还是一个单体项目,不是不想拆是拆不了。问题就出在「自然生长」上,YouTube代码有典型的分层和业务模块分离设计,但是在这个开发团队规模上,很难有一个独裁架构师管控代码设计,工程师为了一些局部优化目标加一些例外破坏原始架构设计,比如在貌似ORM层的地方放业务特定代码,或者为了实现功能跨模块直接调用。Code review能保证局部代码设计合理,高覆盖的测试能大概保证上线能跑,但长期下来那么多工程师那么多例外,软件整体就变成了一团分层不明,依赖混乱,无法拆分的东西。这是常见的软件工程问题,其实跟Python没什么关系,它在一个Python项目上的体现就是随便改一两行代码都有可能break掉完全不相关的不知什么东西,而且不花至少半个小时跑完至少几千个单元测试你都发现不了(跑完了也不保证能发现就是了),开发者肯定是不爽的,我自己就变成了祥林嫂,至于什么快速开发,从来就不存在。

  由于核心数据库访问逻辑在这团无法拆分的大包里,要加涉及核心数据的功能,只能像滚屎球一样捏着鼻子继续往上加代码。但是对相对独立的新功能,工程师首先考虑的是不再需要用MySQL了 —— Google唯二大规模MySQL部署是广告后台和YouTube, 广告后台切Spanner/F1之后就只剩YouTube了,新功能都被鼓励用Spanner等Google原生存储平台。既然如此,那也就没有那坨Python貌似ORM又不是ORM的代码什么事了,业务逻辑当然就可以写成C++或者Java的后台服务。这时候YouTube就已经是一个Python+MySQL+一大堆C++/Java后台的混合架构。

  真正让YouTuber觉得日子没法过了的,其实还是运行时的问题。由于GIL, Python在多线程环境中很难扩展,YouTube用的是prefork多进程模式。YouTube为了接入Google生产环境以及跟各种Google系统交互,难免要大量调用Google通用的C++库,然而这些C++库全都假定是在一个典型的单进程多线程环境下跑的,开几个后台线程,加载一个共享数据表稀松平常,因为它们都假定这些都是给几千个线程共享的资源开销平摊下来没什么,但到了YouTube的多进程环境就尴尬了,最直接的影响就是巨大的内存占用,那些年内存价格高企,问题就尤其突出。CPU单核性能不再提高之后,CPU开销也成了大问题。YouTube尝试过PyPy, 但是发现由于之前明显的CPU瓶颈已经被用C模块的方法优化掉了,接下来上PyPy并没有带来期望的明显性能提升。从profiler上看到的就是做大型复杂工程的人熟悉的:处处都性能不佳,处处都不是瓶颈的景象,软件太复杂,响应最简单的请求都要做很多免不了的事,就得花那么多CPU. pypy-stm 还很不成熟,破除GIL带来的prefork魔咒遥遥无期。走投无路之下YouTube甚至搞过Grumpy(y) 这种疯狂的东西,就是一个用Go写的Python runtime, 企图用goroutine和将Python代码渐进移植成Go的方法破除性能屏障,项目似乎理所当然地没有了下文。光从性能上说另一个有希望的方向是Cython, 然而就像上面说的,明显CPU瓶颈已经用手写C模块优化过了,要再广泛铺开Cython必然要手工改写大量业务代码,话说既然都要手工改写了,那为什么还用Python呢?

  花开两朵各表一支,在codebase上,YouTuber历尽千辛万苦,还是将代码分出来严格的Web前端和API层,API层严格划分出了服务模块,各层和模块间只能采用Protocol Buffer的RPC API交互。虽然由于各种不得已这个严格划分好了的Python codebase(居然)还是要整体发布,但是现在逐个模块重写,至少在技术上成了可能。

  轰轰烈烈的 #YTFExit 运动开始了(YTFE = YouTube FrontEnd),运动还有一个契机:MySQL是真的撑不住了,就算技术上撑得住,Google SRE也不愿再为YouTube维护一套全Google唯一的巨型MySQL环境了。YouTube决定将所有存储迁移到Spanner, 并且重新设计表结构,那坨绕不开的数据访问Python代码横竖都是要重写的了。YouTube决定将API层的服务逐个用C++重写成独立部署的微服务,最大限度利用Google完善的C++ infrastructure, prefork什么的自然不会存在,性能的话,其实不管用什么语言只要把陈年代码推倒重写一次都能有显著提升,更别说是C++了。最后只剩下Web层还是Python, 而由于YouTube Web前端已经迁移到Polymer, 可以直接跟API层通信,需要服务器拼接Web页面的地方越来越少,剩下的Web层代码也越来越少,最终也将迁出Python体系。YouTube也将不再是一个Python项目了。

  YouTube的故事就讲到这里。YouTube无疑是一个使用Python的成功项目,但Python是否就是YouTube各个时期最好的选择,每个参与者都有自己的结论。我们可以问很多假设性问题,像是假如YouTube是个独立公司不需要依赖其他Google软件,会不会在运行时问题上没那么痛苦,有更多优化的机会;假如及早在架构上严格拆分,开发效率是否就不会掉得这么严重;假如早年在用Go写Vitess的时候咬咬牙把YTFE也用Go重写了项目发展会不会更顺利。要是去深入思考每一个假如,就会发现这从来不是一个单纯的语言技术问题。

  我自己的看法是,在一个大团队,长期开发的项目中,「自然生长」和滚屎球难以避免,在因此导致的软件复杂和冗余面前,单纯写代码的速度没有什么意义,在技术上能对项目有帮助的主要是 1. 编译和静态分析速度要快 2. 有个靠谱的运行时。Python在这两方面都没能做得很好(pytype没能在YouTube大规模铺开,因为对YouTube的规模来说它实在太慢了),不是说Python就一定做不好,只是在这个领域选择太多,为什么非要抱着Python不放?社区和生态系统就没有选择往这方面优化。#YTFExit 最终的选择居然是 C++, 要说C++在很多方面也非常不适合现代大型项目,比如编译时间就不及格,但是架不住那么多非C++不可的地方Google不得不下死力气优化,也符合了YouTube的要求。#YTFExit没有选择Go的最大考量是C++互操作性不好,如果不是因为Google的这个C++马太效应,要我开始一个YouTube这样的大型Web项目,我会选择Go.

  当然命运没有给我这个如果,我离开YouTube后去了搞一个大型机器学习项目。本以为逃出了YouTube的焦油坑,结果到项目第一天就被糊了一脸稀烂的Python code. Python成了机器学习默认语言这事也有很多偶然,不过已是既成事实,对构建神经网络的前端DSL是Python这件事我没有什么意见。其实一个机器学习项目除了这一点神经网络构建外其他大部分的工作都是各种倒腾protobuf数据,我认为这是非常不适合Python的东西,但是既然Python是机器学习默认语言,大部分researcher开始倒腾数据的时候也是直接上Python, 你跟谁说理去?也许以后Python社区能大力出奇迹,让语言和生态变得特别适应这类的大型项目。所以一个语言的命运啊,当然要靠自我奋斗,但是也要考虑到历史的行程,这个显而易见的道理知乎小编认为政治敏感,摊手。

  依稀记得大学毕业刚刚到北京来的第一家公司接手一个运营后台的项目,当时一个函数超过 1000 行,然后随处可见该函数的 copy/paste 变体,代码行数破万简直不要太轻松,捧着代码读的时候眼里全是泪(然后我就跑路了- -

  后来的工作中,手里维护的 CodeBase,最多的一个项目 Q,在峰值的时候,纯逻辑 3w 行 Python 代码,加上测试总计 4.5w 行代码,全为面向用户业务(无 HTML 渲染,无后台开发,只提供 HTTP API 与 RPC。核心维护者始终保持在 1-2 人,每天构建新版本部署,少则 1-3 次,多则 10-20 次,不存在 copy/paste 代码。去年 8 月底的时候,用户数超过 2 亿。在快速迭代与可维护性方面,都做得不错。

  怎么算大型项目呢?目前很多公司都在推行服务化/微服务化,整个公司算作一个大型项目,那纯 Python 代码早早就超过了 10w 行。如果只是按照 Monolith CodeBase 来看,上述的项目随着业务的需要继续扩展也没什么问题。

  在大型项目上,语言没有那么重要。架构设计,围绕项目诞生的工具链与生态,测试等因素都要远远大于语言本身的特性,也没遇到 Python 项目不能维护的情况。

  至于 Python 本身的一些语言特性的缺点,在各种语言的对比与争论中有足够多的讨论。

  我就吐槽一句那些拿 Facebook 举例来说明 Python/JavaScript/PHP 作为动态类型语言可以胜任大型项目,只要人牛逼啥都不是问题的。

  就这样大家还天天吐槽静态分析慢,类型标得太弱,类型不够 sound,导致运行时有「本可以被类型系统抓住的」异常……

  你以为的「动态语言灵活快速表达力强还不用写类型标注自己就能 scale」其实并不存在,scale 起来还是得当静态语言写,该加的约束基本都得加回来。(你看 Python 不也屁颠屁颠加 type hint 去了,JS 社区 Flow/TypeScript 如日中天)

  Gradual Typing 很大的问题是很多团队很难像 FB 这样有这么强的约束,即使 FB 也有不少untyped 老代码或者类型标注得太弱(比如 any, object, function),那实际使用的效果很容易就跟 untyped 一样了。最差情况下静态分析时 type check 一遍(不灵活快速),运行时 type check 一遍也不敢做优化(性能负担),最后类型系统还不 sound……

  动态类型和 Gradual Typing 各自的好处很多人说过了不赘述,这里只是关于需要很多人很多年的「大项目」,要知道 FB 是 monorepo……

  项目的大小,不是看有多少行代码,而是看需要多少个工程师,以及多少组工程师,多少部门协作。python的劣势是无法通过单纯的阅读代码进行静态分析。python的优势是可以动态开发,语法简洁,表达力强。但是大型项目里很少有环境可以把动态开发(边运行边开发)的优势发挥出来。大型项目的开发往往是通过静态分析(读代码)和单元测试驱动的。静态分析上c++等静态类型语言有巨大的先天优势。所以单纯从语言角度而言,python相比c++不适合多人跨组合作。

  但是如果只有几个开发者,那么交流成本极大降低,静态分析困难的问题可以通过注释,代码规范,单元测试等诸多方法缓解,这时候python完全可以做非常复杂的项目。比如instgram。instagram在被fb收购以前也是小团队。而像YouTube这种巨型团队,使用python就经常捉襟见肘。

  用python通常比其他语言,特别是Java,体验好太多了。python能让你集中精力处理核心逻辑,几乎不需要为语言本身分心。而java,基本上多一半时间都是在思考语言和框架该如何用。

  在过去十多年中,我用过很多种语言,包括小众一些的如lisp,python是我认为对工程师最友好的语言,而且margin巨大。

  首先是上面定义了一个Slice类型。然后我们的函数输入一个ndarray,输出Slice和int。(其实Slice的名字起的不是很好,有点混淆。)

  这里输入是两个相邻的Slice,输出是其邻接矩阵。邻接矩阵的尺寸为L*R。

  但是问题在于,python可以写成这样却不强制你写成这样。因此很多人就懒得去写。

  其实稍微大一点的库,其类型注解都非常完善,因此你在调用一个函数后,ide总能正确识别返回的类型,并帮助你做自动补全。

  网上有个项目叫mypy,会强行检查你的类型注解,但是却很少人用。我还是希望python社区能够出现一个像typescript一样的东西,比如说typepython。并且大厂有意识往typepython上做兼容。这样开发大型项目时,就可以把python列为可选项之一了。

  随着技术的进步以及程序员自身眼界的提升,很多你以前以为的大型项目其实都只能算是小项目。

  十万行在当今主流观点来看还真不能算什么大项目。很多网站也就这个规格,其实算不得大项目,只能算中项目,用python当然也无不可,并没有什么原则性问题。

  若是千万行级别的项目,用python还是会非常困难的。也许python项目就不会涨到那么大吧。

  以前的雇主,是3-4万人大厂,最核心业务有一个核心大数据系统python写的:

  我全程参与,负责1/4/5/6部分,最保守计算,全套50万行python这个量级肯定有的

  做了好几年,离职回国才开始看zhihu,第一次在zhihu上听说python不适合写大项目。当然,也有可能各位口中的大项目都是那种好几百万行上千万行的,那种我倒真没有经验。

  但这不改变python写起来飞快、生态完备、在技术够的情况下可折腾的东西特别多等等优点。现在我用Golang最多,回想上面项目部分比如第六项爬虫相关那个,当时用Python做,从头到底几个人一个月时间就上线,我不认为Golang可以这么快。第一版上线一个月完成的东西包括:

  ec2上spot instance一个独立的竞价库,在规定的时限、预算目标、爬虫性能预估模型基础上,可以尽力去拍卖竞购所需要的计算资源提供平台。

  爬整个alexa ranking前100万排名的网站的头几层页面,根据其内容选择数万和我们所需要信息相关的网站,把它们全站爬一次。初次爬,要求24小时内出结果。

  一个自己设计的web mining组合算法,从上述爬回来的几个T的数据里挖出我们有价值的某类产品信息。注意,数万网站、数百万网页格式,直接regex/xpath都是完全没有用的。数万网站涉及M个国家、N种语言。

  和内部一个百万级数据的产品数据库整合,把上述爬回来处理好的数据做成一个“网上如此描述本产品”的功能,展示一段机器通过上述挖掘处理以后的数据的综述。

  和内部一个百万级数据的产品数据库整合,把上述爬回来处理好的数据中出现的却无法匹配到我方内部数据的产品做置信评估,选出数万高置信的,供人工分析、排查并最终。

  国内互联网圈子最关键的问题是水平不高,人却自大了。知乎上无意义的讨论某个语言好、某个语言不好,似乎特别起劲。反正cool的东西99%的团队做不出那是肯定的,反正可以来知乎怪语言、怪系统、怪体制,总之都是别人的错,写代码的小白最正确!

  欢迎来怼。我的发言的核心思想就一条:国内互联网圈子这种从来没有成功设计推广过任何一种语言的总体上公认技术落后的团体,成天从python怼到golang,只是在反复给明眼人解释为什么国内技术落后。各主流语言的编译器、runtime、标准库等等都开源了,空谈真的误事,你觉得哪个语言哪个方面不好,请拿出你的解决方案和实现来说话,哪怕你的pull request被否决掉了,请给出详情,大家就事论事看解决方案。还请键盘侠们回归技术人员的淳朴本质,吹骗混蒙的方式开口闭口某个语言怎么怎么有问题,真的很low很丢脸。

  很多年轻新入行的朋友评论区的留言让我感觉他们其实是现在行业浮躁氛围的受害者。我没有能力说去一一帮助他们,但愿意提供一些CS PhD毕业全职写代码很多年的过来人的意见:

  语言是有好坏,肯定要有所选择,但除非你是做编译器、标准库等直接语言方向的,过度关注语言就是本末倒置。

  最容易走弯路形成这种本末倒置的原因就是没有自己一个感兴趣且擅长的CS领域。数据库、大数据、分布式、人工智能、机器学习、图形学、UI、操作系统、高性能、安全、理论计算等等等等领域,不去好好选几个自己喜欢的然后持续投入,过度关注语言这种工具,自己亏太大了。

  当你身边有人并非从事语言直接相关的工作,但开口闭口就是这个流行的语言有这样那样毛病,那个小众语言多优美高效,千万要看清楚,此人不是已经走了上述弯路,就是靠谈语言来吹、蒙、混、骗。

  语言不是一个可以长久获得回报的东西。C++在15年前很热,Java/C#在10年前很热,Python热了几年了,Golang这几年开始热了。但你真的只能年轻一次,投入在语言上不值得,成天在网上和人吹Python多烂Golang多差,其实最对不起自己。

  我发现这个问题下面,有很多人不停地在吹什么:“语言永远不核心,只有人是关键。”“小心点不就完了?你不小心出了问题它就烂?”

  恕我直言,这些人的格局还停留在“工程师”的级别,根本就没有学会从整个项目的角度去看问题。

  当我们在讨论一个百人为单位的大项目的时候,个人的小心与否是根本不重要的,我们看的是一个整体的犯错概率,以及随之而来的人工成本。

  首先,在正式开始之前,我想先在一个问题上和诸位达成基本共识:Python的一项重要优势就是语法的简洁,而简洁是要付出代价的。具体来说,就是牺牲了一些看起来不太重要的细节,比如函数的参数类型和返回类型。但缺少了这些看起来不太起眼的细节之后,程序员会更容易写出一些很难发现的BUG。

  这段我就不举具体的例子了,因为我发现举完例子之后很多人都把关注点放在这两个例子上了。这里我们直接上统计数据吧,来自另一位答主贴出来的资料:

  我们对编程语言和使用进行了大规模的研究,因为它涉及到软件质量。我们使用的 Github 上的数据,具有很高的复杂性和多个维度上的差异的特性。我们的样本数量允许我们对编程语言效果以及在控制一些混杂因素的情况下,对编程语言、应用领域和缺陷类型之间的相互作用,进行一个混合方法的研究。研究数据显示,函数式语言是好于过程化语言的;不允许隐式类型转换的语言是好于允许隐式类型转换的语言的;

  管理内存的语言是好于非管理的语言的。进一步讲,编程语言的缺陷倾向与软件应用领域并没有关联。另外,每个编程语言更多是与特定的 bug 类别有关联,而不是与全部 bug。

  好,如果你对Python更容易写出一些很难发现的BUG这一点没有异议的话,我们可以继续了。

  我知道说到这里,就有人要开始骂我菜,说“小心点不就完了?你不小心出了问题它就烂?”问题是,我们讨论的东西,是大型商业项目啊,跟你某一个工程师小心不小心有个毛毛关系?

  我们给Python个面子,假设程序员水平不错,单元测试做得也很细致,甚至搭建了完善的CI系统(事实上大部分项目做不到这一点),以至于一个程序员每天用Python写出这种高成本BUG的概率只有千分之五(也就是说一年大约才写一个BUG)。我们的项目规模也不大,只雇了500个程序员。

  那么最后,这个项目每天不出高成本BUG的概率有多大呢?我们套个简单的离散二项分布公式:

  我们再进一步,假设每当写出一个隐秘的高成本BUG时,就像例子里那样,会有一个5人小组付出4小时时间反复调查和调试,那么一天时间我们预计会浪费多少人时呢?

  也就是说,我们一天就有起码50人时的资源会浪费在这种毫无必要的BUG上。这样说可能还不够直观,我们不妨假设我们这个项目花了90天完成吧,基于2017年5月这份报告可以计算出“国内3~4年经验的Python程序员平均时薪136.06元”,那么三个月的项目我们总计会浪费

  也就是说,哪怕你已经掏钱建成了CI系统,花了大量人力编写单元测试,Python仍然有办法三个月浪费掉你六十万人民币!

  所以说,求求你们醒一醒,别再不停说什么“小心就没问题了”、“都是你不小心”。在那种百人为单位的大型项目里,你一个程序员小心与否,对于整个项目来说连零头都算不上。

  如果你们有人完整读完之后,仍然坚持嚷嚷着“我就要用Python写大型项目!”、“Python写大型项目没问题的,不就是钱吗?”、“只要充钱你就会变得更强!”,那请把您的联系方式私信给我,我非常盼望能将您引荐给竞争对手。

  Python是门好语言,尤其适合各种敏捷开发和搭建原型,但是再好的语言也架不住你们胡吹……

  Linux内核去年一年就有4000个开发者贡献了代码,不过那个不是全职所以不是很有参考价值。但是与之对标的话,Windows、iOS/MacOS应该是同一个量级的。

  中国这边的IT公司人数比较多,百人甚至千人都可以比较轻松地凑出来,比如华为内部的话我知道若干个五百人左右的大团队。腾讯我有学弟在做游戏开发,所以也有所耳闻。

  当然,我说的这种大团队肯定不可能是500人专注于打造一个小功能,一般的结构是,五人一个小团队,专注于一个具体的小功能,然后小功能凑成一个大系统,比如阿里云之类的。

  我正文中已经反复强调过了,千分之五指的是“这种错误”发生的概率,具体来说,就是前提里面列举的那些“只有Python这样没有类型检查的语言才会犯的错误”。Rust我不是很了解,不过以我熟知的几款静态类型语言而言,犯不出我说的那几个错误。

  而且,不管你是用CI还是用Linter,我都已经把它们设定得很强了。千分之五的概率,平均下来一个程序员一年才会写出一个这样的BUG,这么给力的CI你还甩锅给它,不太合适吧?

  还有,500人以上的项目我在评论区列举过很多,但500人的Python项目让人觉得闻所未闻,也从侧面反映出了我所说的问题。

  嗯是,但是引入第三方类型检测工具之后,还要再加上类型检测工具的成本、部署类型检测的服务器成本。

  而且,并不是你花了这笔钱就把所有漏洞都堵上了。比如我举的第一个例子,即使你引入了类型检测工具,在类型检测工具看来,这个counter从头到尾都是string类型,并没有任何不妥。

  这样的错误,归根结底是因为Python不支持显式声明变量类型,如果Python能显式声明变量类型的话,直接写int counter = ... 这样一句,绝对不会写出这种BUG来。

  我个人觉得最理想的方案,是Python在语法里面把这些丢掉的细节捡回来,但是又不是强制要求开发者一定要写这些声明。这样的话,做小项目的时候我仍然能享受简洁快捷的语法,做大项目的时候我又可以通过Linter强制所有开发者把细节写清楚。

  这个问题我觉得就比较见仁见智了,起码据我的观察而言,Python做大型项目开发根本没有提高多少效率。语法里面省掉的那点东西,在写注释的时候全要一个不漏的都加回去。说Python动态语言可扩展性好,可大项目里加上了强制的PyLint之后,也没有比静态类型语言更方便。顶多是省了几个interface的重构,但是Go语言和Java 8的新语法里面,interface都已经自由很多了,效率感觉不比Python低多少。

  Python开发的时候那种无拘无束地瞎写的快乐,我只有在自己做小项目的时候能体会到。而做大项目的时候,一般会有很繁琐的UT和Lint过程,每个函数都要比着模板把参数类型返回类型写个清清楚楚,不然PyLint根本不认。有时候你的逻辑是对的,可集成测试的时候Linter出了BUG,你还得想办法和Linter斗智斗勇,说服它你用的类型是正确的类型,我觉得这比隔壁用Go的团队痛苦多了。

  最近在写程序的时候为Python没有Type的事情抓狂了一阵,看到这个问题所以不禁来回答一下。在大型项目上,Python 是个烂语言吗?是又不是。什么意思呢?就是它有些缺陷不适合大型项目,但同时又有自己的优势,所以很多大型项目还是会用Python,关键就看怎么规避缺点发挥长处了。

  大型项目很需要Type,而Python没有。其实别说是大型项目了,我个人写的research用的code,也就几千行,过了一段时间回去用我都忘了某个函数的返回值、参数列表是什么东西了,还得看源代码,真是让我自己都抓狂。还好自己早年为此就养成了一个习惯,在函数定义的文档字符中标明每个参数和返回值的具体含义、以及预期的类型,让这个回忆的过程变得容易了一点。现在好的项目文档里面都是可以做到这一点的。

  一个个人项目都暴露出来的问题,在大型团队项目只会被放大成千上万倍。这也是Python在大型项目上被诟病的最多的问题之一。不过这个问题也不是没有解决(缓解)方法。自从Python 3.5之后,type hint被加入了官方的功能(有的地方叫type annotation)。你写代码的时候可以这么写了:

  基本的意思就是你可以声明变量的类型。不过呢,这个跟真正typed language的声明变量类型还是不一样的,Python没有编译器,所以你传入不符合类型的变量运行的时候不会报错。这个东西的主要作用是为了让IDE能够推断变量类型,然后给出合理的预测的。总之,是为了人服务的。

  第二个问题就是速度慢,让Python有时候难以胜任。不过呢,这个问题也有很多解决方法,最常见的就是Cython或者把速度瓶颈的地方用C/C++重写再用Python封装。所以这个问题也是可以绕过去的。

  至于Python的优点,那当然就是写的爽咯。用Python写程序的速度是很快的(很多时候甚至可以称为无脑),想要实现自己的想法可以快速验证,这是Python的优势。人都是喜欢偷懒的,所以有很多大型项目一开始为了搭建原型方便用了Python,后面就一直用着了。然后就不停地解决已存在的问题,比如上面的type hint和速度问题。

  现实中的情况往往不是一刀切的,一个大型项目很可能是是多语言混合的,没必要把自己框死在一个语言上,发挥各个语言的长处就行了。而Python很可能就是上层用来写一些很好用的脚本的,比如深度学习。Tensorflow和Pytorch之类的框架也不算小项目,就是多语言混合的典范。

  知乎后端业务很多是 Python 写的,基本每个微服务代码量都至少是几万行的规模。各个项目加起来没有百万行也至少是几十万行的规模。现在基本上 java,go,Python 都有。有人拿office这种 pc 时代的大型单体软件举例是不恰当的。Python一般很少用来写 pc 桌面软件,互联网时代后端语言也不可能有像 office 这样的庞大的单体软件,项目大了为了能快速开发争取上线速度和业务迭代速度,项目稍微大了肯定是要拆分的(微服务)。不同语言都是有各自使用场景的,Python的使用场景一般在爬虫、web后端、数据分析、量化投资、机器学习等领域。

  有同事比较痛恨动态语言的,觉得维护起来心累。之前有学术研究专门统计过github上不同语言项目的出错率,结论就是静态语言确实更不易出错,维护性更好。动态语言就需要良好的工程实践来控制,不过灵活性更高,表达能力更强。如果真的是超大型单体项目,静态语言确实是个更优的选择,这个是有统计结果作为支撑的。参考这篇文章的研究:

  文章很长,这里我直接贴下这个研究的结论(注意 Python 是动态强类型语言,动态指的是类型检查发生在运行期而不是编译期,强类型指的是不允许隐式类型转换,而不是像js/php 这种可以直接允许一个字符和一个数字直接相加):

  我们对编程语言和使用进行了大规模的研究,因为它涉及到软件质量。我们使用的 Github 上的数据,具有很高的复杂性和多个维度上的差异的特性。我们的样本数量允许我们对编程语言效果以及在控制一些混杂因素的情况下,对编程语言、应用领域和缺陷类型之间的相互作用,进行一个混合方法的研究。研究数据显示,函数式语言是好于过程化语言的;不允许隐式类型转换的语言是好于允许隐式类型转换的语言的;静态类型的语言是好于动态类型的语言的;管理内存的语言是好于非管理的语言的。进一步讲,编程语言的缺陷倾向与软件应用领域并没有关联。另外,每个编程语言更多是与特定的 bug 类别有关联,而不是与全部 bug。

  js/python/ruby 等脚本语言是在互联网时代才逐渐流行的,互联网时代软件慢慢从桌面转移到了网站和移动端,而网站后端基本 java/php/nodejs/python/ruby/golang 等都有广泛的使用。

  互联网公司很少用单体架构了(不会像一个桌面软件那样成百上千万行),一个服务代码量过大对于项目维护,开发,部署,上线都是灾难(想象一下几十个人甚至上百人维护一个项目仓库,每天光解决冲突就够你受的了,公司可能早就在激烈的产品迭代竞争中死掉了),很多都是微服务架构。微服务架构下很多语言都能胜任,几乎都有商业项目的成功案例,甚至很多动态语言快速构建原型反而更有优势,即使将来遇到了瓶颈重构一个服务也不会太难。大的网站往往是靠架构,而脚本语言的应用也主要是在互联网而不是传统桌面软件。

  下边是一些知名Python 项目的代码量统计,目前最大的Python 项目应该是openstack了,达到了百万行,不过大部分大项目最多也就是几十万行。如果是商业项目,目前不太可能出现一个项目百万行的情况。国内目前很多用Python 的还是中小公司,只可能有大的网站或应用,不太可能出现一个超大的单体项目,项目大了迟早要业务拆分。如果项目组的人员不排斥写Python ,Python 是可以用在很多项目上的,并且在爬虫,网站,数据分析等领域Python 都有比较成熟的解决方案,一开始真的没必要过于纠结技术选型,可能工程控制,代码质量反而比较重要。技术选型本来就是在权衡嘛,尽量扬长避短。

  不过很多小公司不重视代码质量管理(比如无注释、无文档、无单测、无静态检测、无规范、无code review等),用动态语言是有很大风险的,将来肯定会遇到各种修修补补,上线就跪了的情况,这种时候还是慎用动态语言瞎搞,否则代码仓库迟早会难以维护甚至失控。

  Type hint目前不是强制检查的情况下,Python确实是个烂语言。

  如果以后能够强制检查Type hint,再改善一下performance,Python做大型工程问题就不大了。

  原型先从Ducking type开始写,然后发现了bug就加type hint就行。这样可靠性和快速开发就能兼得了。

  ,这点是无法否认的。并且这种问题通过『提升程序员的素质』这种方式并不是很管用。

  静态语言引以为傲的类型检查,现在 Python 3.7 内置了 Type Annotation,

  Python 的创始人带头搞了 MyPy 这个项目用于解决类型检查的问题。

  当项目代码质量很差的时候不仅仅可以考虑是不是强类型和弱类型的问题,还有如下的问题需要考虑

  7.1 Code Review 是不是做了。为了炫技而炫技的 Python 代码不应该通过。KISS 原则必须要遵守。 7.2 持续集成 CI 和 unit test 和 functional test 做了没?是不是要提升一下代码覆盖率? 7.3 是不是应该花点时间补充测试然后重构了? 7.4 是不是应该多花时间尽量理解需求方的背后目的,梳理完沟通完毕再动手写代码。 7.5 有没有好好的打日志?Sentry 了解一下? 7.6 常用的 workflow 是不是该写到 makefile 里面,拷贝到身边,一用很多年?

  假如你还是觉得加类型检查比较好,类型错误这种低级错误确实不能忍,那么 Python 的 Type Annotation 可以用起来了。

  可以在真实环境中非常方便的运行局部代码,甚至可以在 ipy 里面完成一波调试之后,把调整好的代码拷贝回源代码中,然后 make staging 之后速度 reload ipython 继续调试。

  第二点可能有些静态语言的使用者,比如 Javaer 可能感受不到。我来举个栗子。

  我现在需要到生产环境上把 redis 里面的缓存的帖子 id 为 xxx,xxx,xx,xx 的里面的活动重置一下状态,如果重置成功,则把 redis 里面的 key 删掉。

  我直接 ssh 到机器上,make shell 进入环境。执行如下代码:

  但是如果你说....CPython 的性能差搞不起大项目,我是无法反驳的.... 毕竟你说的是实话

  没有足够的文档、单元和集成测试、没有类型系统,重构的时候完全就看工程师的脑子和记忆力,换几个人这个系统马上进入 legacy 维护模式,然后又来知乎上吐槽前任写的代码多傻逼。就这种工程理解,你们不996,谁996?

  Guido从G家离开后不久G家唯一的大型Python内部项目就推倒重写了。回答完毕。

  借着Type Annotate的东风,Google已经下大力气开发google/pytype让现有代码的可维护性增加很多。如果当年有pytype的话,那个大型Python内部项目可能就不重写而是重构了。

【感兴趣,请留言】
姓名:
联系方式:
联系方式:

提示:感谢您的支持,提交成功后工作人员将尽快与您取得联系!

相似项目
  • 项目型IT公司向产品型IT公司演进的
    2013年春节期间,不经意阅读了《乔布斯传》,使我了解到一个产...
    融资资金:
    所属行业:
  • 在大型项目上Python 是个烂语言吗?
    最近在pongba的google groups看到一个较火的讨论:python是个烂语言。...
    融资资金:
    所属行业:
您使用的浏览器版本过低,不仅存在较多的安全漏洞,也无法完美支持最新的web技术和标准,请更新高版本浏览器!!
留言上传成功 感谢您的支持
确 定