22.1 引言/动机
22.1.1 什么是扩展
一般来说,所有能被整合或导入到其他Python脚本的代码,都可以称为扩展。您可以用纯Python来写扩展,也可以用C和C++之类的编译型语言来写扩展(或者也可以用Java给Jython写扩展,也可以用C#或Visual Basic.NET给IronPython写扩展)。
Python的一大特点就是,扩展和解释器之间的交互方式与普通的Python模块完全一样。Python在设计之初就考虑到要让模块的导入机制足够抽象,抽象到让使用模块的代码无法了解到模块的具体实现细节。除非那个程序员在磁盘中搜索这个模块文件,否则,他就连这个模块到底是用Python写的,还是用某种编译语言写的都分辨不出来。
核心笔记:在不同平台上创建扩展
我们要注意的是,如果你曾自己编译过Python解释器,那么,在这样的环境中,扩展一般都是可以使用的。自己手动编译扩展,和获取扩展的二进制文件是有些不同的。虽然自己编译比简单地下载安装复杂一些,但由此得来的好处就是,你可以自由选择你想使用的Python版本。虽然本章中的例子都是在Unix系统中开发的(一般的Unix中都自带编译器)。但只要你能使用C/C++(或Java)的编译器并且在C/C++(或Java)中有Python的开发环境,那唯一的区别只是怎样来编译而已。无论在哪一个平台上,真正起作用的代码都是一样的。如果你在Win32平台上进行开发,你需要有Visual C++开发环境。Python的发布包中自带了7.1版本的项目文件。当然,你也可以使用老版本的VC。想了解更多的关于如何在Win32上开发扩展的信息,你可以访问如下网页
http://docs.python.org/ext/building-on-windows.html
警告:就算是相同架构的两台电脑之间最好也不要互相共享二进制文件。最好是在各自的电脑上编译Python和扩展,因为有时就算是编译器或是CPU之间的些许差异,也会导致代码不能正常工作。
22.1.2 为什么要扩展Python
纵观软件工程的历史,编程语言都不具备可扩展性,你只能使用已有的功能,而不能为语言增加新功能。现如今的编程环境中,可定制性也是一个很大的卖点,它可以促进代码的复用。TCL和Python等语言是第一批提供可扩展性的语言。那么,为什么我们会想要扩展像Python这种已经很完善的语言呢?有以下几点好理由。
- 添加/额外的(非Python)功能
扩展Python的一个原因就是对一些新功能的需要,而Python语言的核心部分并没有提供这些功能。这时,通过纯Python代码或者编译扩展都可以做到。但是有些情况,比如创建新的数据类型或者将Python嵌入到其他已经存在的应用程序中,则必须得编译。
- 性能瓶颈的效率提升
众所周知,由于解释型的语言是在运行时动态地翻译解释代码,这导致其运行速度比编译型的语言慢。一般说来,把所有代码都放到扩展中,可以提升软件的整体性能。但有时由于时间与精力有限,这样做并不划算。
通常,先做一个简单的代码性能测试,看看瓶颈在哪里,然后把瓶颈部分在扩展中实现会是一个比较简单有效的做法。效果立竿见影不说,而且还不用花费太多的时间与精力。
- 保持专有源代码私密
创建扩展的另一个很重要的原因是脚本语言都有一个共同的缺陷,那就是所有的脚本语言执行的都是源代码,这样一来源代码的保密性便无从谈起了。
把一部分代码从Python转到编译语言就可以保持专有源代码私密,因为你只要发布二进制文件就可以了。编译后的文件相对来说更不容易被反向工程出来。因此,代码能实现保密。尤其是涉及到特殊的算法、加密方法及软件安全的时候,这样做就显得非常至关重要了。
另一种对代码保密的方法是只发布预编译后的。pyc文件。这是介于发布源代码(.py文件)和把代码移植到扩展这两种方法之间的一种较好的折中方法。