Sunday, December 07, 2008

[Python]Python 3.0来了

经历了3年的开发,Python 3.0 (Py3k)在千呼万唤声中 ,终于在2008年12月3号正式发布了。用Guido同学(Python语言的缔造者)自己的话说,Python这些年经历了迅猛发展,已经开始有点违背了Python的"There's Only One Way To Do It"的哲学理念。Guido同学认为Python之所以有今天正是得益与这一与Perl "There is more than one way to do it"相反的理念。所以他需要做一些“清理门户”的事情。因此,我们就有了Python 3.0这一"里程碑"--Python 3.0不提供向下兼容性。换言之,你的2.x的库或者代码,可能会无法运行在Python 3.x当中。

Python 3.0当中有哪些变化呢?http://docs.python.org/3.0/whatsnew/3.0.html给出了官方的解释。首先映入眼帘的便是,print的语法被改变了。如今print降格为了普通一介函数,需要用print(file=xxx, str1, str2,...)来调用了。其实我很怀念原先print>>xxx, str1, str2 ...的语法,简洁而一目了然。

另外我觉得比较大的改变还有
  • dict.keys() dict.values()以及dict.items()不再返回list类型的值。所以如果想要k=d.keys();k.sort() 就得写成 k=sorted(d)
  • range现在像以前的xrange那样来工作(之前range直接返回一个list而xrange是返回一个可以yield同样结果的迭代器,以提高效率)。xrange下岗了。
  • 1/2现在的结果是float了,如果要得到截尾的效果,需要用1//2。这个好,再也不用痛苦的写上a*1.0/b/c了
  • <>下岗了。现在只能用!=了。这点不理解。
  • list.sort()现在可以多一个key 参数。比如list.sort(key=myhash),则myhash为一个1参数1返回的函数,list就依据这个myhash来对其包含的元素排序。乌拉!这点好,不用再去重载cmp函数了。早就盼着这一天了
  • 支持如同ML当中的pattern matching: (a, *rest, b) = range(5)
    可以得到 a=0, rest=[1,2,3], b=4
  • 终于到了我最关心的一点:Python 3.0里提供了函数参数以及返回值的注解功能。比如你可以 定义函数 def foo(para1: "the 1st input", para2: "the 2nd input") -> "final result" 这里使用了字符串作为参数和返回值的注解。或者你可以 def bar(para1: int, para2: list) -> float 这样来用类型定义。不过需要特别指出的是,python解释器本身不对注解做出任何反应。这里注解的作用是提供给第三方来infer参数意义或者做typechecking的。
说道这里,就稍微走题一下吧。Python是一种Dynamic Typing的语言。变量的类型是在运行期才infer出来,而不像C/C++/Java等Static Typing在编译期就已经决定了。Dynamic Typing的优点在于方便灵活,但如果程序规模一大,纠错就是一个很头疼的事情。Static Typing 很多错误可以在编译期就发现。我自己的一个感觉就是用Java写程序如果“编译”通过了,运行期出错的概率比Python小的多。所以一直都很希望Python能有可选的Static Typing 的功能。事实上,Boo 就是一种Static Typing的Python-like语言,而Cobra 则是提供了可选Static Typing的Python-like语言。关于Python是否需要这一功能,可以看一下Guido同学的帖子"Adding Optional Static Typing to Python"。总体而言可以说Guido同学是反对这一想法的。因为他觉得这会把Python简洁的语法弄的凌乱而丑陋并且对Python解释器的执行速度也是一大考验。回到Python 3.0的注解机制上来,这算是一种折中吧--如果你需要typecheking, OK,我们提供场地,你请用第三方来完成吧,但是后果你自负。好吧,虽然这不是我想要的,但是总比没有强吧。

Python 3.0究竟会表现如何?时间会告诉我们,让我们拭目以待。

No comments: