【编者按】今年12月3日、4日,Python界著名的PyCon大会首次登陆中国,邀请了众多国内的Python高手作为嘉宾,带来了很多精彩演讲。InfoQ有幸邀请了几位与会嘉宾就广大Python爱好者所关心的问题发表了各自的观点。
近些年Python在语言特性的发展上,有什么值得称道的地方,又有什么需要改进的地方?
洪强宁:Python语言最近的发展我比较关心的有两个——Python 3和 PyPy。
Python 3的动机是修正之前Python版本中一些设计不合理的地方,所以不兼容旧版本。但由于其实Python 2中那些“不太合理的地方”并不是很干扰开发,大家都已经习惯了,而Python 3特别吸引人的新特性并不多(nonlocal是我的最爱),因此相对而言,为了升级而必须解决兼容性问题的工作量显得投入产出比过大,并不合算。这就导致大量项目迟迟不提供对Python 3的支持,而依赖这些项目的其他项目因此也难以迁移到Python 3。如果Python 3能够有更多激动人心的特性支持的话(比如更强大和好用的lambda),整个社区的迁移过程应该会快很多。
PyPy是一个很有意思的项目,JIT、去掉GIL、更好的垃圾收集机制、Stackless支持我认为都是正确的方向。如果PyPy能够成为主流,对于有性能要求的服务端开发,会是一件很好的事情。当然PyPy目前还不够成熟,比如不支持CPython的 C extension ,这就大大限制了它的使用。性能提升除了它自己的Benchmark的数据外,也还需要有更多成功案例的支持。
周琦(Zoom.Quiet):Python 3毅然决然地坚定高速发展,在广泛接受建议的同时,Guido还会解决所有以前设计的问题,非常值得期待。PyPy / Jython / Cython / Parallel Python等项目得益于Python的开源,各种Python实现都在快速发展,它们也解决了各种领域问题。一句话,Python在健康强壮的发展中。
需要改进的就是Python 3的模块迁移一直没有很好的解决方案,期望在完成Python 3的稳定版本开发后Guido可以将精力关注到这方面。不过, execnet已给出了一个很好的过渡方案——以execnet为中介,Python 3主程序可以直接使用Python 2的兼容模块!
李迎辉(Limodou):Python 3代表了Python未来发展的趋势,它的内部越来越一致,比如内部Unicode的统一,这样将减少字符串编码转換带来的一些麻烦。当然,在不断向完善过程发展的同时,也带来一些向前的不兼容性,好在还有2.7作为过渡,以及提供2to3程序来辅助转換,这在一定程度上会减少转換带来的麻烦。不足之处依然存在,比如GIL还无法去除。另外个人感觉Ruby和Javascript中的闭包是一个不错的特性,也许可以吸收进来。
赖勇浩:Python这些年一直在发展,从2.6到3.2版本的发布都是非常给力的,在3.x持续增加新特性的同时还发布新的2.6、2.7 版本把这些新特性放入2.x分枝,Python 开发者无论选择哪一个大版本都能得到充分的尊重——这是最为难能可贵的、值得称道的。
关于它需要改进的地方,我觉得已经不多了,因为一些Bad Smell的问题已经在3.x版本中得到了根本性的修正。不过我在2010 年11月底的时候写过一篇博客 《我想要的Python特性》,里面谈到3个Python目前没有提供的特性,分别是在函数式编程、设计模式和面向消息编程方面的增强,但从文章的评论来看,赞同和抵制的人基本相当。关于面向消息编程,我自己实现了一个 python-message开源库,已经在我主持的一个商业项目中使用,能够很好地解耦模块关系,在PyCon也作了简单的宣传,在此再向大家推荐。
黄冬:Python语言最让我关心的事情是多核处理器和PyPy。
Python从最早的只能使用系统的标准fork进行多进程实现,但是进程管理较其它语言的多核支持差点多。后来加入了multiprocessing,使得通过多进程能更为方便的使用多进程从而达到多核的使用。Python一直把自己放在一个更接近于操作系统的极别,所以它更喜欢自己像C一样的与操作系统打交道,这即是一个优点,同样也少了很多方便的特性。
PyPy则是一个非常有意思的东西,它将一个去掉GIL的世界带了进来,同时JIT可以让我们更快的运行起来,这样让Python从一个运行时的解释形态,走入了一个全新的状态。非常期待它的新特性加入进来。
未来,我认为更好的支持多核和更好的操作系统特性支持,将会是一个非常重要的改进方向。
您觉得在移动互联网和Big Data兴起的今天,Python的机会在哪里?
周琦:Python一向是有机会的,只是以往受到Nokia的扼制,现在更加自在而已。个人感觉Python在3大方向上都能有所作为:随着CommonJS思想的兴起,我认为在Node.js / Objective-C这类新兴语言的DSL实现时直接选择Python的语法也有可能,这也算是Python在移动时代的另类发展吧。
- 传统的服务端开发,配合HTML5的各种API服务开发,Python是最敏捷的
- 大规模的手机应用自动化测试,Python的强力内存探测功能,可以直接对C / C++ / Java应用进行测试,以后也将包含Objective-C
- 嵌入式应用,随着各个平台的不断开放,将tinypy嵌入到手机里,作为原生驱动的调用界面
李迎辉:Python一方面作为通用的开发语言,具备清晰、易读、开发效率高并且包含丰富的库的特点,我觉得移动互联特别需要能够快速开发的语言,以实现需求的快速响应,而Python的确可以满足这方面的要求。另一方面,Python又作为一种“胶水”语言,可以方便实现与C / C++等语言的互相调用,因此既可以满足某些关键环境性能的要求,又可以充分利用现有资源。所以在专业领域我们仍然可以继续使用原有的技术,同时可以充分发挥Python的“胶水”特性,以快速构建所需要的应用。
黄冬:Python做为处处可用的语言,移动互联网的很多Web服务都用其进行开发,因为Python高效且严谨的语言特性而为大家喜爱,更重要的是它在开发效率和性能方面找到了一个非常良好的折中点。
我自己在大量的移动互联网公司看到Python支撑着他们的Web服务、后台业务处理、数据清洗与加工处理等各个环节。唯一遗憾的是,Python在移动互联网的今天还是没有在前端走出来,但是有所长必有所短,发挥语言的特性、实现价值没有什么不好。
在使用Python的时候,是否有遇到过性能上的问题,是如何解决的?
赖勇浩:有的,就像以前使用C++的时候一样。无论使用什么编程语言,都会遇到性能问题。性能问题的根源不是编程语言,而是业务。举个例子,你说C++执行效率高吧,写个CPU软件渲染图形游戏引擎跑一下Unreal Engine 3提供的特性试试看有没有性能问题?在PyCon的快速演讲环节中,阿里云的产品经理李俊东先生就鲜明地提出自己的观点——不要迷恋语言性能,要多关注业务性能!遇上 Python性能问题的时候,解决方案与其它语言遇上性能问题是类似的,有以下步骤:更细节的内容,不妨参考我博客的 几篇文章。
- 使用Profiler确定性能瓶颈
- 使用更适合的数据结构与算法、更合理的I/O模型、更少的运算(如缓存之前的运算结果)
- 使用更快的编程语言重写瓶颈部分,就像用C++时使用汇编指令重写那样
李迎辉:性能问题产生的原因有很多,一方面可能是由于Python语言本身带来的,因此这块可以考虑通过C / C++来进行改造;另外pypy也可能是一个发展的方向,它通过即时编译来提高Python执行效率。另一方面可能是由于设计造成的,这块就无法仅通过语言的优化来实现,可能更多通过架构设计、集群计算、软硬件相结合等办法来解决。
多进程部署和协程似乎已经成为了一种趋势,在大会上很多嘉宾都谈到了这方面的内容,您是怎么认为的?
沈崴:赖勇浩在大会上说“协程才是未来”,这句话我很赞同。多线程用来维护上下文,开发成本低但是并发性能差;传统的异步模型,并发能力强但是开发成本高,而且很难有效框架化。协程没有这两方面的缺陷,并兼具他们的优点。当前大家都比较关注协程的性能优势,但是协程的核心,应该是以线程逻辑来维护上下文,以极低的成本来实现高并发。单从性能上讲,协程相比传统异步模型并没有优势,开发效率的革命性提升,这才是关键。我们使用协程已有五年多的时间,相较传统模式协程所具有的压倒性优势,我们深有感触。协程就是未来。
多进程部署则是另一个范畴,进程、线程其实都可以与协程一起很好地工作,我在大会演讲中也有提到。同时根据会上一些嘉宾的观点,线程他们其实用得并不多,对我们来讲,面对多线程也是采取知难而退的态度。相对线程而言进程却有着根本性的区别,从传统上讲多进程涉及的范畴非常广,从多核、机器间协作到云计算等。一直以来能否正确运用多进程都是架构设计的核心本质,从目前我们接触到的一些流行的架构设计案例来看,要做到这一点其实并不容易。对很多架构设计者而言,要学好多进程部署还有很长一段路要走。
洪强宁:与单进程多线程模型相比,多进程和协程是更加Scalable的模型。在高并发场景下,采用多进程模型编制的程序更加容易Scale Out,而协程模型可以使单机的并发性能大幅提升,达到Scale Up的目的。所以,未来服务器端并发模型的标配估计会是:每个核一个进程,每个进程是用协程实现的微线程。
在编码方面,多线程模型带来的共享资源加解锁的问题一直是程序员的梦魇。而用多进程模型编程时,会自然鼓励程序员写出避免共享资源的程序,从而提高鲁棒性。而Python目前的协程实现都为非抢占式调度,程序员自行控制协程切换时机,因此也可以避免绝大多数令人头疼的加解锁问题。这些都利于写出更稳定的代码。
另外,和同样具有很好并发性能的事件驱动模型相比,用协程实现的微线程,在逻辑表达上非常友好和直白,无须在不知道什么时候会发生的event和一层套一层的callback中纠结和扭曲(正如 Twisted其名)。对于写过多线程程序的程序员而言,协程带来的微线程模型几乎可以实现无痛提高并发性能。
我一直是个协程的鼓吹者,并坚信这是服务端编程的正确方向。所以希望大家把Twisted踩在脚下,忘掉 Tornado,把精力放到 gevent和其他基于协程的框架上来吧。
李迎辉:这些方面更多是集中在后台服务器方面的开发,在网络后台、游戏服务器开发等应用比较多。多进程没什么好说的,因为它实现方便,而且因为GIL问题的存在,现在是比较好的并发处理模式。而协程也更多是为了充分利用I/O资源,因此也有它使用的局限性。所以如果对服务开发有兴趣的不仿多了解一些这方面的内容。Python除了做服务器开发,还有许多的开发领域,所以你的开发兴趣不在这方面,暂时不了解也没有关系。
赖勇浩:在未来,起码在脚本语言的世界里,线程的地盘一定会进一步缩小。在Lua和Ruby 中,你看不到原生线程的存在,但它们还是流行了。充分说明哪怕是多核时代,线程也不受待见。相对于获取更佳的 CPU 并行计算性能,现代的程序员更乐于获取更佳的代码可维护性,因为现代项目已经非常庞大,运行在多台计算机甚至多个数据中心上,榨取单机性能显得有点舍本逐末。我个人浅见是在未来线程会有点像C++的处境,它不会被淘汰,但会被限制在编写为多核优化的程序库等领域,一个能够CPU并行计算的Python 库的确是有吸引力的,但普通的业务逻辑程序员就不碰线程为妙了。
黄冬:其实Python在原生多进程上支持非常优美,只是它没有提供一个原生VM来屏蔽系统级多进程操作复杂。我认为有两个方法,等待一个更为优美的解决方案的出现,或者耐心看看Python已经比原生fork更酷的实现吧。gevent这样的框架是高性能服务器的必然选择,它更轻更简单,更好的利用了libevent的特性,时代在前进,相信它也会更为成熟的。
您认为像Python这样的动态语言应用在开发大型项目或企业级开发的时候有什么局限性?
沈崴:我想说Python确实不太适合用来开发大型项目。我听许多业内的朋友说,他们用Python做软件,人力成本和项目周期经常只是竞争对手的一个零头。这很糟糕,这意味着任意一个大型项目到Python这里几乎都会变成小项目。相反,任何一个再普通不过的需求使用某些流行语言开发,都有机会演变成大型项目。这很好地解释了为什么很少听说Python有什么大项目,而其他语言的大项目总是很多的原因,这也是Python被误认为缺乏大规模开发特性的原因。这也掩盖了一个事实,如果你仔细观察就会发现Python在各个领域其实都扮演着极其重要的角色,虽然他会很低调。
在这个时代,代码规模和程序员痛苦指数已经不再是评判项目规模和员工绩效的有效标准,我们的公司主管们需要尽快地习惯这一点。同时对Python程序员而言,往往是轻描淡写地把任务完成了,这时你需要尽量克制住把程序做成大项目的冲动,这对项目是非常危险的,也是不负责任的。喜欢通过大型项目证明自己是典型的初学者心态,Python程序员不需要这个。因此我会说Python不太适合用来开发大型项目,虽然有点答非所问,但还是希望对大家会有点用。
洪强宁:说实话我没有觉得在开发大型项目(豆瓣的网站算大型项目吗?)上Python有什么局限性。相反,在开发大型项目时,由于人员协作变得重要,代码可维护性的重要性凸显。使用Python更容易写出简单易读风格一致的代码,语言本身的高抽象能力可以大幅降低代码量,强大的语法和良好的包管理机制使得重构变得容易。这些都很好的提高了代码的可维护性,所以我强烈推荐使用Python进行大型项目开发。
如果一定要说有什么局限性的话,那就是动态语言难以做静态分析,所以不像静态语言很多问题可以在编译期发现。但配合上完善的自动化测试(这个无论是用静态语言还是动态语言开发项目都应该是必需的),这个问题可以很好的解决。
对“企业级开发”的定义不太清楚,因此不好做什么评价。
李迎辉:首先可能是标准化的问题。因为Python没有企业应用级别的应用标准,所以无法实现类似J2EE一样的应用标准架构,所以更多还是看设计人员个人的水平发挥。另外就是Python虽然自带了许多组件,但是没有完整的针对企业的套件,而且也没有相应的商业化支持,所以还无法形成相应的开发规模,企业也不愿意投入。再加上,国内Python语言开发还不是主流,没有形成规模化,更多的Python开发集中在Web和游戏方面,企业级开发的研究和投入不足,Python程序员还比较少,所以很难形成相应的市场。
周琦:简单的说,没有!严格的说,只有成员招聘、文化重塑的麻烦。
优秀的Python开发者一直都不太容易找得到,在人员的培养和招聘方面您有什么心得?
沈崴:因为Python上手容易,所以招聘的选择面反而非常宽。你其实并不关心应聘者是否熟练地使用了 Java,又或者能否担当C++各种开发陷阱的活字典,当然要形成这些技能确实需要许多年或者几十年的工作经验,而现在这些都不重要。如今你将开始关心一些更为本质的东西,程序员应有的悟性以及灵性,比如快速学习的能力、洞察力,以及是否热爱编程。
我们这里不仅有Java开发者还有.Net程序员,既有资深工程师也有应届毕业生,他们无一例外都能很好地玩转Python。同时我们的培训专注于稳固扎实的基础,能够掌握和重现各种底层原理。再结合Python强大的实现能力,就能轻松完成许多让普通程序员感觉非常头痛或者根本无法完成的任务。
李迎辉:的确,现在国内招聘Python的越来越多,但是从个人角度来说因为Python的开发还不太上规模,相应的职业体系和培训机制还没有建立,所以更多人员是靠自学成才,但是这样远远无法满足企业招聘的需求。而且目前许多Python程序员和其它的程序员不同,他们大多是对开发本身有着强烈的兴趣,因此这些人的水平和素质相应要高于其它的程序员群体,所以也造成这样的人才在数量上也的确不会太多。所以我觉得一方面要靠市场本身来孕育更多的Python程序员,另一方面我个人建议如果企业能在培训、在活动、在支持开源社区上多投入,一方面宣传自已另一方面可以多发展有兴趣的程序员,从而形成良性循环。而目的的情况是,Python相关的活动比较少,并且大多是自由发起,所以还没有形成比较好的环境。
赖勇浩:无论什么编程语言,优秀的开发者都不太容易找到。给优秀人才想要的,无论是物质还是感情,你身边自然能够聚焦高手。如果又要马儿跑,又要马儿不吃草,请先摆正你的心态。所以如果招不到优秀人才,不妨从如下三个方向入手:一是改变业务逻辑,降低技术难度,自然不需要优秀人才了;二是另找一条路,比如你一直想找更快的马,找不到的时候不妨买辆汽车,说回来就是换套解决方案,比如 Python程序员不好找,你用C# / Java不就得了,说不定还更好;三是加强自己的修为,所谓物以类聚人以群分,你很强大,自然容易找到强大的合作者。
周琦:Python本身如此简单,使程序员可以在第一时间关注业务实现本身,而不是语言特性。所以,招聘也好培养也好,都关注实战就好。可以看看一直以来在推广Python的 蟒营。
黄冬:其实所有使用C的人使用Python都很快,Java上手Python也很快,但是,无论哪种语言,优秀的开发者本身就很少。人员的培养都是相似的,树立技术价值观,建立好的人员筛选和目标设定、评估体系,这与任何一种工作、任何一家公司都一样。招聘当然要去Python社区了,邮件列表、开源项目都是优秀的Python开发者的藏身之处。
对于打算尝试Python的开发者和企业,您有什么建议?
周琦:Python世界早已自足,只要相信,就无所不能。
李迎辉:尝试Python没有错,许许多多失败的例子并不是因为选择了某种语言,更多还是人的因素。所以我觉得要想成功,更多的是在语言之外的东西。所以我的建议是认定方向就要坚持,踏实不浮燥,多考虑其它成功的项目,多与其他人进行沟通和交流。
赖勇浩:对于开发者,我觉得多学一门编程语言肯定不错,利用业余时间学一下大有增益;但切忌随便看点书或文章就下了结论认为这东西无所不能或一文不值,要学就学深入一点。对于企业,我的看法是不要轻易尝试,哪怕PyCon的讲师说得天花乱坠。引入新的技术就是引入新的风险,对之前的技术架构、员工情绪、企业文化都会带来巨大冲击,除非你已经考虑清楚愿意为这件事情折腾到脱一层皮都在所不惜。