python3教程Python状况:为什么Py是P的未来?

2019-02-09 05:15

python3教程Python状况:为什么Py是P的未来?



  Python 现在已经不仅仅是胶水脚本语言了,不信?看看下面使用Python的成功案例:

  目前高级语言可以写出简单具有灵活性的代码,所以在快速创建应用程序的时候是一个不错的选择, 你不需要花时间来处理各种数据类型 (所有接口示例代码都是为了满足编译处理),可能有些人就会争论了,这个特性会产生有bug的代码, 但是 Guido van Rossum说:“生产的代码谁会不经过测试呢”? 静态语言在编译时期就能处理一些错误,但这并不能检测出所有的错误, 最后你还是得编写测试代码。 而有这个时间完全可以为动态语言写出测试代码,此外人们还不能设计一个堪称完美的类型系统,对此Jim Treavor写了一些总结。

  现在Python非常流行,同时它的地位也受到竞争者的挑战。Python有良好的生态系统,也有大型软件和社区支持,但它缺乏其竞争者的高效和先进的运行环境。

  正如我在开头说的一个特点,Python很容易连接各种编译库,这是它作为胶水语言在20年前流行的重要原因。但是目前依然活跃的工具已经很老旧了,你必须花大量精力才能使用它们。

  c 扩展是邪恶的, 它们绑定到Python的特定版本还不能被重复使用, 更糟糕的是, CPython2和CPython3的c 扩展 API不一样,想想将库移植到Python3会是什么情况吧!

  Cython - 这是被设计用来编写C扩展的,但是我敢确定,使用C扩展是你最后想做的事,Cython 是一个需要编译的外部工具, 它最终的代码并没有动态行为,但是它的语法还需要学习,Cython不支持类型推断,使用Cpython你不得不去编译, Cython也不是一个标准, 它不能作为解释代码来执行_nuitka_的作者 Kay Hayen在Static Compilation - That is the point总结的非常好。

  swig, boost - 这些是非常容易的, 通常修改下C/C++ 代码就可以了, 或者写一些方案文件。

  相比之下,有很多新的工具能在相同的性能下(甚至超出),更好的处理这些任务。

  cffi - 一个能轻松处理你的c库的包。在接触硬件或者支持其他软件时你会经常做这样的事(像数据库客户端、驱动程序)。尝试下在python里使用它是多么简单吧。你不需要写任何的封装,类型化代码。而且还有 CPython 和 PyPy 的支持。

  胶水语言也有另一面。我们来想想底层高性能编程的过程。可能看起来会是下面几个过程:

  很多复杂的底层代码和组织机构代码。很可能是一堆晦涩的泛型代码(为了重用性)。

  感谢Python的简便性、脚本语言的本质和大量的工具,将他作为你代码的模板和核心。这就意味着你只需要写最少的底层代码,让Python做剩下的事:生成组织代码和你的底层代码需要的环境。

  这与以往Lisp的理念一样,代码即数据,代码能够被其他正在执行的代码理解(代码可以作为数据被处理)。因而机器可以理解运行时正在执行的代码,并且去优化它,通过通常的方式就能得到全部的数据信息,而不用像C++那样使用模板。这是C++和其他流行的编程语言所没有的。最终我们有相对更底层的抽象级别,而运行时信息相对更丰富,使得编译器可以:

  为未知的硬件做特化 (编码时),包括支持的数据类型,以及可用的优化方法。

  人们不用为数据类型烦恼(运行时环境就已经可以保证快速、正确使用数据类型)

  一点Python代码(最棒的部分),用来构建整个架构。然后是一些底层的代码 ,同样很棒,因为这些代码没有恶心的模板和上下文代码。事实上,底层的代码也可以通过Python代码生成。

  有很多方法能用Python写出高速的代码。最流行而且仍在广泛传播的方法是,用底层语言来写应用里最复杂的部分,然后使用,这对python来说无疑是很不幸的事。

  所有Python里出色的高效的工具都需要许多复杂的c代码,这阻碍了其他的贡献者进来。现在我们想要写出高速而且美观的python代码。

  有很多工具可以把python代码编译成机器代码,比如:Nuitka, Python2C, Shedskin, pythran。我认为它们都是失败的,当你使用它们的时候,就需要跟动态行为说再见了。他们只支持一部分的python语言,并且离完全支持还有很大距离。我甚至不认为以后他们能做到。另外他们也没有用那些使JIT(Just-In-Time 运行时编译执行)的解决方案变得出色的先进的技术和运行时信息。

  为了让下一步的开发更简单,实现动态语言的最佳状态,Python需要一个合适的架构。当前CPython的架构过于简单,因而限制比较大,很难做到像JIT编译器那样的功能。下面是一些在增强CPython解释器性能上的失败的努力:

  还有一些尝试修复CPython一些缺陷的尝试: Stackless和HotPy,但是Guido (Python之父,仁慈的独裁者) 的坚持使得这些项目没有被合并到Python中。(说明一下,HotPy还不是产品级的东西)。

  CPython最大的问题是他的C API,这部分没有很好的设计。其他部分的实现多少都受此影响。

  在公共库中停止对CPython的底层属性(C API,C扩展)的依赖。作为替代,采用有如下功能的中间工具:

  cython - 编写可移植的C扩展。我并不推荐它用于通常的编程,不过它确实在维护C扩展方面更好一些,也更简单。Cython已经有CPython和PyPy后端。

  PyPy为优化和进一步的语言开发提供了更好的架构。对于大部分Python已有的问题,PyPy已经提供了解决方案:

  速度 - PyPy内置的JIT很棒,有时(其实很少)甚至可以与C相提并论。

  GIL问题 - PyPy引入了一个很棒的STM实现,在 Armins Rigo的 文章中对此作了介绍。

  粘合代码 - 使用cffi可以简单的处理C库,甚至比CPython的ctypes还要快!

  异步编程。这方面,PyPy内置的 greenlet 比CPython的C扩展更适合一些。实际上,非堆栈式的概念(也即greenlet)在PyPy中还在继续发展。

  PyPy同时还包含了一个优秀的现代的架构,在 Jim Huang 的演讲 中做了介绍,演讲的要点是:

  用于研究和产品的组件组合 (不同的数据模型,垃圾回收 - 这些可以在具体的应用场景进行改变)

  构建在基于组件链的功能架构之上(翻译工具链)。每一个步骤都会延续/转换程序模型、引入特征、各种后端(JVM, JavaScript, LLVM, GCC IR等等)。来看一下翻译链的例子:python 代码 -> 字节码 -> 函数对象 -> 类型推断 -> 垃圾收集器 -> JIT

  相信让所有软件支持PyPy需要付出艰巨的努力 - 需要在现有的库上做很多工作。不过使用新的工具,编写支持PyPy和CPython的软件会比采用C扩展的方式更简单一些。