不老的新丁Python何以让人着迷(转载)

不老的新丁Python何以让人着迷

     为什么要学习Python(英语发音:/ˈpaɪθən/)?Python的特点是什么?这里借用一位大师的话:他的语言是与时代同步,而Python则是未雨绸缪,而且计划得颇为出色。下面就让我们走进Python的世界,感受Python的力量。

Python是一门美丽的语言。它简单易学,跨平台,而且运转良好。达成了许多Java一直求索的技术目标。一言以蔽之就是:其他的语言是与时代同步,而Python则是未雨绸缪,而且计划得颇为出色。当然,这句话出自一位大师之言。为什么要学习Python呢?Python果真就有这么大的魅力吗?

51CTO推荐阅读:全能选手 看看Python应乎潮流的72变

特点

尽管Python已经流行了超过15年,但是一些人仍旧认为相对于通用软件开发产业而言,它还是个新丁。我们应当谨慎地使用“相对”这个词,因为“网络时代”的程序开发,几年看上去就像几十年。

当人们询问:“什么是Python?”的时候,很难用任何一个具象来描述它。人们更倾向于一口气不加思索地说出他们对Python的所有感觉,Python是___(请填写)__,这些特点究竟又是什么呢?为了让你能知其所以然,我们下面会对这些特点进行逐一地阐释。

高级

伴随着每一代编程语言的产生,我们会达到一个新的高度。汇编语言是上帝献给那些挣扎在机器代码中的人的礼物,后来有了FORTRAN、C和Pascal语言,它们将计算提升到了崭新的高度,并且开创了软件开发行业。伴随着C语言诞生了更多的像C++、Java这样的现代编译语言。我们没有止步于此,于是有了强大的、可以进行系统调用的解释型脚本语言,例如Tcl、Perl和Python。

这些语言都有高级的数据结构,这样就减少了以前“框架”开发需要的时间。像Python中的列表(大小可变的数组)和字典(哈希表)就是内建于语言本身的。在核心语言中提供这些重要的构建单元,可以鼓励人们使用它们,缩短开发时间与代码量,产生出可读性更好的代码。

在C语言中,对于混杂数组(Python中的列表)和哈希表(Python中的字典)还没有相应的标准库,所以它们经常被重复实现,并被复制到每个新项目中去。这个过程混乱而且容易产生错误。C++使用标准模版库改进了这种情况,但是标准模版库是很难与Python内建的列表和字典的简洁和易读相提并论的。

面向对象

建议:面向对象编程为数据和逻辑相分离的结构化和过程化编程添加了新的活力。面向对象编程支持将特定的行为、特性以及和/或功能与它们要处理或所代表的数据结合在一起。Python的面向对象的特性是与生俱来的。然而,Python绝不想Java或Ruby仅仅是一门面向对象语言,事实上它融汇了多种编程风格。例如,它甚至借鉴了一些像Lisp和Haskell这样的函数语言的特性。

可升级

大家常常将Python与批处理或Unix系统下的shell相提并论。简单的shell脚本可以用来处理简单的任务,就算它们可以在长度上(无限度的)增长,但是功能总会有所穷尽。Shell脚本的代码重用度很低,因此,你只能止步于小项目。实际上,即使一些小项目也可能导致脚本又臭又长。Python却不是这样,你可以不断地在各个项目中完善你的代码,添加额外的新的或者现存的Python元素,也可以重用您脑海中的代码。Python提倡简洁的代码设计、高级的数据结构和模块化的组件,这些特点可以让你在提升项目的范围和规模的同时,确保灵活性、一致性并缩短必要的调试时间。

可升级”这个术语最经常用于衡量硬件的负载,通常指为系统添加了新的硬件后带来的性能提升。我们乐于在这里对这个引述概念加以区分,我们试图用“可升级”来传达一种观念,这就是:Python提供了基本的开发模块,你可以在它上面开发你的软件,而且当这些需要扩展和增长时,Python的可插入性和模块化架构则能使你的项目生机盎然和易于管理。

可扩展

就算你的项目中有大量的Python代码,你也依旧可以有条不紊地通过将其分离为多个文件或模块加以组织管理。而且你可以从一个模块中选取代码,而从另一个模块中读取属性。更棒的是,对于所有模块,Python的访问语法都是相同的。不管这个模块是Python标准库中的还是你一分钟之前创造的,哪怕是你用其他语言写的扩展都没问题!借助这些特点,你会感觉自己根据需要“扩展”了这门语言,而且你已经这么做了。

代码中的瓶颈,可能是在性能分析中总排在前面的那些热门或者一些特别强调性能的地方,可以作为Python扩展用C重写。。需要重申的是,这些接口和纯Python模块的接口是一模一样的,乃至代码和对象的访问方法也是如出一辙的。唯一不同的是,这些代码为性能带来了显著的提升。自然,这全部取决你的应用程序以及它对资源的需求情况。很多时候,使用编译型代码重写程序的瓶颈部分绝对是益处多多的,因为它能明显提升整体性能。

程序设计语言中的这种可扩展性使得工程师能够灵活附加或定制工具,缩短开发周期。虽然像C、C++乃至Java等主流第三代语言(3GL)都拥有该特性,但是这么容易地使用C编写扩展确实是Python的优势。此外,还有像PyRex这样的工具,允许C和Python混合编程,使编写扩展更加轻而易举,因为它会把所有的代码都转换成C语言代码。因为Python的标准实现是使用C语言完成的(也就是CPython),所以要使用C和C++编写Python扩展。Python的Java实现被称作Jython,要使用Java编写其扩展。最后,还有IronPython,这是针对.NET或Mono平台的C#实现。你可以使用C#或者VB.Net扩展IronPython。

可移植性

在各种不同的系统上可以看到Python的身影,这是由于在今天的计算机领域,Python取得了持续快速的成长。因为Python是用C写的,又由于C的可移植性,使得Python可以运行在任何带有ANSIC编译器的平台上。尽管有一些针对不同平台开发的特有模块,但是在任何一个平台上用Python开发的通用软件都可以稍事修改或者原封不动的在其他平台上运行。这种可移植性既适用于不同的架构,也适用于不同的操作系统。

易学

Python关键字少、结构简单、语法清晰。这样就使得学习者可以在相对更短的时间内轻松上手。对初学者而言,可能感觉比较新鲜的东西可能就是Python的面向对象特点了。那些还未能全部精通OOP(ObjectOrientedProgramming,面向对象的程序设计)的人对径直使用Python还是有所顾忌的,但是OOP并非必须或者强制的。入门也是很简单的,你可以先稍加涉猎,等到有所准备之后才开始使用。

易读

Python与其他语言显著的差异是,它没有其他语言通常用来访问变量、定义代码块和进行模式匹配的命令式符号。通常这些符号包括:美元符号($)、分号(;)、波浪号(~)等等。没有这些分神的家伙,Python代码变得更加定义清晰和易于阅读。让很多程序员沮丧(或者欣慰)的是,不像其他语言,Python没有给你多少机会使你能够写出晦涩难懂的代码,而是让其他人很快就能理解你写的代码,反之亦然。

如前所述,一门语言的可读性让它更易于学习。我们甚至敢冒昧的声称,即使对那些之前连一行Python代码都没看过的人来说,那些代码也是相当容易理解的。看看下一章节——“起步”中的例子,然后告诉我们你的进展是多么神速。

易维护

源代码维护是软件开发生命周期的组成部分。只要不被其他软件取代或者被放弃使用,你的软件通常会保持继续的再开发。这通常可比一个程序员在一家公司的在职时间要长得多了。Python项目的成功很大程度上要归功于其源代码的易于维护,当然这也要视代码长度和复杂度而定。然而,得出这个结论并不难,因为Python本身就是易于学习和阅读的。Python另外一个激动人心的优势就是,当你在阅读自己六个月之前写的脚本程序的时候,不会把自己搞得一头雾水,也不需要借助参考手册才能读懂自己的软件。

健壮性

没有什么能够比允许程序员在错误发生的时候根据出错条件提供处理机制更有效的了。针对错误,Python提供了“安全合理”的退出机制,让程序员能掌控局面。一旦你的Python由于错误崩溃,解释程序就会转出一个“堆栈跟踪”,那里面有可用到的全部信息,包括你程序崩溃的原因以及是那段代码(文件名、行数、行数调用等等)出错了。这些错误被称为异常。

如果在运行时发生这样的错误,Python使你能够监控这些错误并进行处理。这些异常处理可以采取相应的措施,例如解决问题、重定向程序流、执行清除或维护步骤、正常关闭应用程序、亦或干脆忽略掉。无论如何,这都可以有效的缩减开发周期中的调试环节。

Python的健壮性对软件设计师和用户而言都是大有助益的。一旦某些错误处理不当,Python也还能提供一些信息,作为某个错误结果而产生的堆栈追踪不仅可以描述错误的类型和位置,还能指出代码所在模块。

高效的快速原型开发工具

我们之前已经提到了Python是多么的易学易读。但是,你或许要问了,BASIC也是如此啊,Python有什么出类拔萃的呢?与那些封闭僵化的语言不同,Python有许多面向其他系统的接口,它的功能足够强大,本身也足够强壮,所以完全可以使用Python开发整个系统的原型。显然,传统的编译型语言也能实现同样的系统建模,但是Python工程方面的简洁性让我们可以在同样的时间内游刃有余的完成相同的工作。

此外,大家已经为Python开发了为数众多的扩展库,所以无论你打算开发什么样的应用程序,都可能找到先行的前辈。你所要做的全部事情,就是来个“即插即用”(当然,也要自行配置一番)!只要你能想得出来,Python模块和包就能帮你实现。Python标准库是很完备的,如果你在其中找不到所需,那么第三方模块或包就会为你完成工作提供可能。

内存管理器

C或者C++最大的弊病在于内存管理是由开发者负责的。所以哪怕是对于一个很少访问、修改和管理内存的应用程序,程序员也必须在执行了基本任务之外履行这些职责。这些加诸在开发者身上的没有必要的负担和责任常常会分散精力。在Python中,由于内存管理是由Python解释器负责的,所以开发人员就可以从内存事务中解放出来,全神贯注于最直接的目标,仅仅致力于开发计划中首要的应用程序。这会使错误更少、程序更健壮、开发周期更短。

解释性和(字节)编译性

Python是一种解释型语言,这意味着开发过程中没有了编译这个环节。一般来说,由于不是以本地机器码运行,纯粹的解释型语言通常比编译型语言运行的慢。然而,类似于Java,Python实际上是字节编译的,其结果就是可以生成一种近似机器语言的中间形式。这不仅改善了Python的性能,还同时使它保持了解释型语言的优点。(转载自: http://developer.51cto.com/art/201009/226531.htm)

 

Python等动态语言企业应用面面观

     尽管动态语言的兴起已经很多年了,与在Web开发中风风火火所不同,在企业级应用中,动态语言仍有不足之处,文章作者结合实例,分析了动态语言在企业应用中的优劣点。

动态语言的兴起已经有些年头了,现在,人们早已不再去争论动态语言是否能够取代静态语言,因为这种争论毫无意义。越来越多的开发者开始在动态语言更为擅长的领域应用它们。

Django和Ruby on Rails等开发框架的盛行使得像Python和Ruby这样的动态语言可以在Web开发领域大放异彩,PHP和JavaScript也早已在Web开发领域占有一席之地。(相关文章推荐:动态语言,别再轻言不)

不过目前动态语言在企业开发中的应用还不够广泛,并没有承担起主力开发语言的重任。尤其是在底层系统开发方面,动态语言远没有在Web开发方面那么风光。

在运行时效率和虚拟机稳定性方面的不足,使得动态语言注定无法与编译型语言竞争,并取代它们在高性能领域的地位。然而,动态语言也有自己的优势所在。如何克服自己的劣势,将优势发扬光大,便是每一位动态语言开发者所面临的机遇和挑战。

动态语言的优势

动态语言的优势有很多,归纳起来主要有以下几个方面:

1. 生产力。动态语言在开发效率方面有着无与伦比的优势,这也与动态语言“优化人的时间而不是机器的时间”这个理念相吻合。利用传统的静态语言要开发几周的功能和特性,使用动态语言也许几天甚至几个小时就可以实现。不仅如此,动态语言在开发原型系统和常用工具方面的开发效率也非常高,尤其值得一提的是原型系统。<?什么是原型系统?>

更快地让原型系统运转起来,不仅可以尽早验证一些假设,也能够更好地与迭代开发相结合,更及时地与需求方进行沟通,帮助需求方挖掘和了解自己真正的需求。开发效率可以说是动态语言最为吸引人的地方,这也被认为是将来开发语言的前进方向。这些年随着敏捷开发的盛行,越来越多的开发者意识到,原来动态语言的特性和敏捷开发的价值观也相当契合:缩短反馈时间,对变化的响应能力更强。

2. 代码量。曾有报道说,用Ruby on Rails写同样的项目,代码量大概只有Java的1/10。且先不说这个说法是否有夸张的成分,但就实际来看,动态语言的确从代码量上来说,要比 Java/C/C++等传统静态编译型语言要少的多(当然语言的表达能力与动态静态关系并不大,静态函数式语言的表达能力也很强),可能几千行的项目就算得上是个大项目。

3. 测试。因为动态语言很容易实现反射等动态特性(JUnit也是等到Java支持了反射以后才出现的),因此测试也更为容易实现。Python和Ruby的标准库中都带有unittest的框架,这几乎可以让你无成本地使用单元测试来加固代码。因为动态语言本身不具有编译过程,因此犯下某些低级错误的几率大大增加,也为重构带来了重重困难。没有单元测试的重构如同梦魇一般,动态语言尤甚。<?什么是单元测试?>

因此,在开发语言以动态语言为主的开源项目中,单元测试总是占有相当大的比重。还有建议称测试代码与生产代码的比率(Unit Test To Code Ratio)要达到2:1以上。另外,动态语言的测试环境更容易搭建,实现Mock也更为简单。

4. 原生数据结构。现在主流的动态语言多为脚本语言发展而来,而在这些语言中,集合、列表和词典这样的数据结构都是原生的,而静态语言的数据结构往往是通过程序类库来实现的。比如Python就提供了set、tuple、list和dict等原生数据结构,同时还提供了大量操作(如数组分片等),让这些数据结构使用起来非常方便。原生数据结构使得对数据的操控融入到了语言的语法当中,让程序更为易读,这也让基于代码的沟通更为顺畅。

5. 简单易学。动态语言的语法相对简单,学习成本看似也比较低。有人举例说,Python和Ruby写个Hello World只需要一行即可,这是很多静态语言所达不到的(把多行代码写成一行的不算)。

当然你可以认为这只不过是句玩笑话,不过单就语法而言,动态语言的学习门槛要比很多静态语言要低的多。可是,开发不仅仅只是语法而已。很多动态语言的初学者,能够用动态语言写一些简单的小程序小工具,却很难构建起庞大复杂的商业系统,究其原因,主要是还是因为系统设计和面向对象的功底欠缺所导致的。如何设计,如何抽象,如何重构,这些能力与语言无关,而是个人的修为。

正如陆游所言,“功夫在诗外”,这些能力也不是一朝一夕、通过学学语言就能够轻易练就的。当然,动态语言的各种特性(如Duck Typing)也使得在静态语言中不得不使用的设计模式可以很自然地表达,这些差异也增加了动态语言学习的隐性成本。

不足之处

任何事物都具有两面性,动态语言也不例外,虽然优势显而易见,动态语言的不足之处也有很多。这里列举一些我们在开发过程中所遇到的问题,以及一些初步的解决方案,来供大家参考。

1. 运行效率。运行效率低下使得动态语言饱受诟病。“跑得太慢”这顶帽子已经在动态语言的头上扣了许多年。甚至有Benchmark表明,在某些应用场景下,动态语言的运行效率和C/C++、Java等成熟的静态语言相比,相差数十倍甚至上百倍,这也为动态语言的普及埋下阴影。不少开发者因为运行效率的问题,纷纷表示 “对动态语言很失望”。其实我倒是觉得大可不必纠结在这个问题上,原因有两点。

第一,很多动态语言的应用场景使得运行效率的重要程度大大降低。就拿 Ruby on Rails来说,在Web开发这个应用场景里,数据库的响应时间无疑是最大时延,与之相比代码运行时间就微不足道了。而且通过Cache和优化,基本上可以消除代码运行效率低对项目的影响。又如我们的消息网关系统,最耗时的部分就是网络通信和文件I/O,而这两部分动态语言和静态语言相比并无明显劣势,运行效率的问题可以完全忽略。

第二,如果遇到很耗CPU或者很耗内存的运算,完全可以通过C/C++实现的扩展来解决。无论是Python还是Ruby,都支持采用C/C++编写扩展。通过这些扩展,可以极大地提高运行效率,从而弥补动态语言在运行效率上的不足。

2. BUG难于发现。动态语言由于没有构建的过程,因此很多错误只有等到运行时才会发现。而这些错误很可能是些低级错误,比如拼写错误、没有import相关的类库,或者括号不匹配等等。如果每次修复这样的BUG都要通过去测试环境中部署来验证的话,则会浪费了大量时间。

因此动态语言往往需要充分的自动化测试套件,才能够确保代码基本可用。另外,使用动态语言的时候,一个良好的代码静态检查工具也是很有必要的。它不但可以纠正一些低级错误,而且还可以帮助你发现代码中的Bad Smells,大大提高开发效率。

对于Python来说,Pyflakes或Pylint都是不错的选择;而Ruby也有众多工具可供使用。测试充分的代码也更容易重构,在重构动态语言项目时要万分小心,因为动态语言极容易犯错,稍不留意就会引入新的BUG。保持小步前进的步伐,每次修改后都执行测试,最好再通过持续集成环境来帮助发现测试失败的情况,这样重构起来才能得心应手。

3. 专业人员少。不少使用动态语言的公司都会遭遇一个问题,那就是使用动态语言的资深开发人员很少,不但很难招聘到靠谱的员工,核心人员的离队也会对公司造成很大的损失。这是因为完全使用动态语言进行开发的公司少的可怜,只有极少数的开发者能够参与其中并获得相关的开发经验。绝大多数的动态语言使用者还处在爱好者阶段,跟着Tutorials写写Demo,或者随手写个Utils等等。

因为高水平的动态语言开发者的确是可遇不可求,因此寻找有经验的开发者也许要花上不少的时间和成本。当团队有了较为有经验的开发者以后,就需要通过内部培训、结对编程等手段,帮助公司里没有经验的开发者迅速积累经验,逐渐成为动态语言方面的靠谱人才。

其实,对于动态语言的圈子,还有一个有趣的说法:因为学习动态语言的人往往都是在其他领域有了很深的积累后,在有余力的情况下才接触动态语言的,因此往往相对都比较靠谱,动态语言的圈子反而能够帮助雇主们甄选出一批高素质的开发者。

4. 不够成熟。动态语言的发展历史虽然不比静态语言差到哪里(比如Ruby和Java就同为1995年始创),然而由于其较为小众,因此无论是虚拟机的实现上,语言本身的机制上,还是相关的配套工具上都算不得十分成熟。

例如,Ruby虽然以其优美灵活的语法为人所称道,但也因为其虚拟机效率低下和内存泄露问题所为人诟病,使用Ruby on Rails的网站往往需要加配监控程序,一旦发现某个VM内存超标立刻重启;Python的虚拟机虽然还算稳定,但长久以来一直受GIL(Global Interpreter Lock获取全局解释器锁 )问题所困扰,完全无法发挥多核的优势,这在家用PC都早已多核的今天的确是个不小的问题(事实上Ruby也存在GIL问题)。

不过,虽然官方实现不够成熟,现在已经有很多逐渐成熟的其他选择可供使用。比如JRuby就充分利用了Java成熟的虚拟机和Ruby优良的语法特性,还可以允许开发者使用Java背后庞大的类库。通过multiprocessing或Stackless Python,甚至手工将任务切成多份,分发给多个进程运行,都可以规避掉GIL的问题,更充分地利用系统性能。

当然,随着时间的推移,动态语言的实现将会越来越成熟,不但MRI逐渐完善,MagLev和Rubinius等一系列优秀的Ruby虚拟机也开始登上舞台;Python 3000甚至打破了向后兼容性,试图将Python以前的设计错误全面改写。回头去看Java等一批成熟开发语言的发展路线,有谁没有经历过不成熟的青春期呢?

小结

通过实践我们发现,动态语言既不是什么洪水猛兽,也不是什么奇巧玩物,它们已经逐渐成长为称手的兵器,帮助开发者们快速完成项目,进而达成商业目标。使用动态语言,已经让我们切切实实感受到了它的开发效率为我们所带来的好处。在商业机会瞬息万变的今天,谁能以最快的速度实现自己的想法,谁能尽快应对市场带来的变化,谁就能离成功更进一步。

诚然,动态语言目前还存在很多问题。但瑕不掩瑜,如果在使用时可以意识到这些问题,并善加处理的话,动态语言也可以成为复杂商业系统的主角,在企业开发中占据自己的地位。而且随着开源社区的努力,很多问题正逐一被解决。我们有理由相信,在不远的未来,动态语言一定会有一片更为广阔的天空。(转载自http://developer.51cto.com/art/201007/210244.htm)


你可能感兴趣的:(不老的新丁Python何以让人着迷(转载))