做设计用的素材下载网站有哪些网站建设案例展示
做设计用的素材下载网站有哪些,网站建设案例展示,恒通建设集团有限公司网站,上海贸易公司名录17、Python 教程 - 扩展 Python
Python 什么都能做#xff0c;真的是这样。这门语言功能强大#xff0c;但有时候 速度有点慢。
鱼和熊掌兼得
本章讨论确实需要进一步提升速度的情形。在这种情况下#xff0c;最佳的解决方案可能不是完全转向 C 语言#xff08;或其他中…17、Python 教程 - 扩展 PythonPython 什么都能做真的是这样。这门语言功能强大但有时候速度有点慢。鱼和熊掌兼得本章讨论确实需要进一步提升速度的情形。在这种情况下最佳的解决方案可能不是完全转向 C 语言或其他中低级语言建议你采用下面的方法这可满足众多的速度至上需求。**1、**使用 Python 开发原型有关原型开发的详细信息请参阅第 19 章**2、**对程序进行性能分析以找出瓶颈有关测试请参阅第 16 章3. 使用 C或者 C、C#、Java、Fortran 等扩展重写瓶颈部分。这样得到的架构包含一个或多个 C 语言组件的 Python 框架将非常强大因为它兼具这两门语言的优点。简单易行的方式Jython 和 IronPython使用 Jythonhttp://jython.org或 IronPythonhttp://ironpython.net可轻松地使用原生模块来扩展 Python。Jython 和 IronPython 能够让你访问底层语言中的模块和类对 Jython 来说底层语言为 Java对 IronPython 来说为 C#和其他.NET 语言一个简单的 Java 类JythonTest.javapublic class JythonTest { public void greeting() { System.out.println(Hello, world!) } }使用 Java 编译器如 javac来编译这个类。javac JythonTest.java编译这个类后启动 Jython并将.class 文件放到当前目录或 Java CLASSPATH 包含的目录中CLASSPATHJythonTest.class jython然后就可直接导入这个类了。import JythonTest test JythonTest() test.greeting()#输出结果如下 Hello, world! 一个简单的 C#类IronPythonTest.csusing System; namespace FePyTest { public class IronPythonTest { public void greeting() { Console.WriteLine(Hello, world!); } } }选择的编译器来编译这个类对于 Microsoft .NET命令如下csc.exe /t:library IronPythonTest.cs要在 IronPython 中使用这个类一种方法是将其编译为动态链接库(DLL)并根据需要修改相关的环境变量如 PATH然后就应该能够像下面这样使用它了这里使用的是 IronPython 交互式解释器import clr clr.AddReferenceToFile(IronPythonTest.dll) import FePyTest f FePyTest.IronPythonTest() f.greeting()编写 C 语言扩展扩展 Python 通常意味着扩展 CPython——使用编程语言 C 实现的 Python 标准版C 语言的动态性不如 Java 和 C#而且对 Python 来说编译后的 C 语言代码也不那么容易理解。因此使用 C 语言编写 Python 扩展时必须遵循严格的 API。其他方法使用 Cpython有很多工具可帮助提高程序的速度这是通过生成和使用 C 语言库或提高 Python 代码的速度实现的。工具描述Cythonhttp://cython.org这其实是一个 Python 编译器它还提供了扩展的 Cython 语言该语言基于 Greg Ewing 开发的项目 Pyrex让你能够使用类似于 Python 的语法添加类型声明和定义 C 类型。因此它的效率非常高并且能够很好地与 C 扩展模块包括 Numpy交互。PyPyhttp://pypy.org这是一个雄心勃勃而有远见的 Python 实现——使用的是 Python。这种实现好像会慢如蜗牛但通过极其复杂的代码分析和编译其性能实际上超过了 CPython。其官网指出“有传言说 PyPy 的秘密目标是在速度上超过 C 语言这是无稽之谈不是吗”PyPy 的核心是 RPython——一种受限的 Python 方言。RPython 擅长自动类型推断等可转换为静态语言、机器码和其他动态语言如 JavaScript。Weavehttp://scipy.orgSciPy 发布版的一部分也有单独的安装包。这个工具让你能够在 Python 代码中以字符串的方式直接包含 C 或 C 代码并无缝地编译和执行这些代码。例如要快速计算一些数学表达式就可使用这个工具。Weave 还可提高使用数字数组的表达式的计算速度。NumPyhttp://numpy.orgNumPy 让你能够使用数字数组这对分析各种形式的数值数据从股票价值到天文图像很有帮助。NumPy 的优点之一是接口简单无需显式地指定众多低级操作。然而NumPy 的主要优点是速度快。对数字数组中的每个元素执行很多常见操作时速度都比使用列表和 for 循环执行同样的操作快得多这是因为隐式循环是直接使用 C 语言实现的。数字数组能够很好地与 Cython 和 Weave 协同工作。ctypeshttps://docs.python.org/library/ctypes.html模块 ctypes 最初是 Thomas Heller 开发的一个项目但现在包含在标准库中。它采用直截了当的方法——能够导入既有共享的 C 语言库。虽然存在一些限制但这可能是访问 C 语言代码的最简单方式之一。不需要包装器也不需要特殊 API只需将库导入就可使用。subprocesshttps://docs.python.org/3/library/subprocess.html模块 subprocess 包含在标准库中标准库中还有一些较老的模块和函数提供了类似的功能。它让你能够在 Python 中运行外部程序并通过命令行参数以及标准输入、输出和错误流与它们通信。如果对速度要求极高的代码可使用几个批处理作业来完成大部分工作启动外部程序并与之通信所需的时间将很短。在这种情况下将 C 语言代码放在独立的程序中并将其作为子进程运行很可能是最整洁的解决方案。PyCXXhttp://cxx.sourceforge.net以前名为 CXX 或 CXX/Objects是一组帮助使用 C 编写 Python 扩展的工具。例如它提供了良好的引用计数支持可减少犯错的机会。SIPhttp://www.riverbankcomputing.co.uk/software/sipSIP 最初是一个开发 GUI 包 PyQt 的工具包含一个代码生成器和一个 Python 模块。它像 SWIG 那样使用规范文件。Boost.Pythonhttp://www.boost.org/libs/python/docBoost.Python 让 Python 和 C 能够无缝地互操作可为你解决引用计数和在 C 中操作 Python 对象提供极大的帮助。一种使用它的主要方式是以类似于 Python 的方式编写 C 代码Boost.Python 中的宏为此提供了支持再使用你喜欢的 C 编译器将这些代码编译成 Python 扩展。它虽然与 SWIG 有天壤之别却能很好地替代 SWIG因此很值得你研究研究。SWIGSWIGhttp://www.swig.org指的是简单包装器和接口生成器simple wrapper and interfacegenerator是一个适用于多种语言的工具。一方面它够使用 C 或 C 编写扩展代码另一方面它自动包装这些代码能够在 Tcl、Python、Perl、Ruby 和 Java 等高级语言中使用它们。SWIG 使用起来很简单前提条件是有一些 C 语言代码1用法(1)为代码编写一个接口文件。这很像 C 语言头文件在比较简单的情况下可直接使用现有的头文件。(2)对接口文件运行 SWIG以自动生成一些额外的 C 语言代码包装器代码。(3)将原来的 C 语言代码和生成的包装器代码一起编译以生成共享库。2回文回文palindrome如 I prefer pi是忽略空格、标点等后正着读和反着读一样的句子。一个简单的检测回文的 C 语言函数palindrome.c#include string.h int is_palindrome(char *text) { int i, nstrlen(text); for (i 0; I n/2; i) { if (text[i] ! text[n-i-1]) return 0; } return 1; }检测回文的 Python 函数def is_palindrome(text): n len(text) for i in range(len(text) // 2): if text[i] ! text[n-i-1]: return False return True3接口文件假设代码存储在文件 palindrome.c 中现在应该在文件 palindrome.i 中添加接口描述。如果定义一个头文件这里为 palindrome.hSWIG 可能能够从中获取所需的信息。在接口文件中只是声明要导出的函数和变量就像在头文件中一样。在接口文件的开头有一个由 %{和 %}界定的部分可在其中指定要包含的头文件这里为 string.h%module 声明用于指定模块名。回文检测库的接口palindrome.i%module palindrome %{ #include string.h %} extern int is_palindrome(char *text);4运行 SWIG 运行 SWIG 时需要将接口文件也可以是头文件作为参数$swig -python palindrome.i这将生成两个新文件分别是palindrome_wrap.c和**palindrome.py**。5编译、链接和使用在 Linux 中使用编译器 gcc$ gcc -c palindrome.c $ gcc -I$PYTHON_HOME -I$PYTHON_HOME/Include -c palindrome_wrap.c $ gcc -shared palindrome.o palindrome_wrap.o -o _palindrome.so将得到一个很有用的文件_palindrome.so。它就是共享库可直接导入到 Python 中条件是它位于 PYTHONPATH 包含的目录中如当前目录中import _palindrome dir(_palindrome)#结果为[__doc__, __file__, __name__, is_palindrome] _palindrome.is_palindrome(ipreferpi)#结果为1 _palindrome.is_palindrome(notlob)#结果为06穿越编译器“魔法森林”的捷径通过使用 Setuptools直接支持 SWIG让你无需手工运行 SWIG只需编写代码和接口文件再运行安装脚本。手工编写扩展SWIG 在幕后做了很多工作但并非每项工作都是绝对必要的。如果你愿意可自己编写包装代码也可在 C 语言代码中直接使用 Python C API。Python/C API 参考手册标准库参考手册1引用计数在 Python 中内存管理是自动完成的你只管创建对象当你不再使用时它们就会消失。在 C 语言中必须显式地释放不再使用的对象更准确地说是内存块否则程序占用的内存将越来越多这称为内存泄漏memory leak。可使用 Python 在幕后使用的内存管理工具其中之一就是引用计数。一个对象只要被代码引用在 C 语言中是有指向它的指针就不应将其释放。为将对象的引用计数加 1 和减 1可使用两个宏分别是 Py_INCREF 和 Py_DECREF。对象不归你所有但指向它的引用归你所有。一个对象的引用计数是指向它的引用的数量。对于归你所有的引用你必须负责在不再需要它时调用 Py_DECREF。对于你暂时借用的引用不应在借用完后调用 Py_DECREF因为这是引用所有者的职责。可通过调用 Py_INCREF 将借来的引用变成自己的。这将创建一个新引用而借来的引用依然归原来的所有者所有。通过参数收到对象后要转移所有权如将其存储起来还是仅仅借用完全由你决定但应清楚地说明。如果函数将在 Python 中调用完全可以只借用因为对象在整个函数调用期间都存在。然而如果函数将在 C 语言中调用就无法保证对象在函数调用期间都存在因此可能应该创建自己的引用并在使用完毕后将其释放。再谈垃圾收集引用计数是一种垃圾收集方式其中的术语“垃圾”指的是程序不再使用的对象。循环垃圾即两个对象相互引用对方导致它们的引用计数不为 0但没有其他的对象引用它们。2扩展框架必须先包含头文件 Python.h再包含其他标准头文件。#include Python.h static PyObject *somename(PyObject *self, PyObject *args) { PyObject *result; Py_INCREF(result); /* 仅当需要时才这样做*/ return result; } int PyArg_ParseTuple(PyObject *args, char *format, ...);3回文另一个回文检查示例palindrome2.c#include Python.h static PyObject *is_palindrome(PyObject *self, PyObject *args) { int i, n; const char *text; int result; if (!PyArg_ParseTuple(args, s, text)) { return NULL; } nstrlen(text); result 1; for (i 0; i n/2; i) { if (text[i] ! text[n-i-1]) { result 0; break; } } return Py_BuildValue(i, result); /* i表示一个整数*/ } static PyMethodDef PalindromeMethods[] { /* 方法/函数列表*/ { is_palindrome, is_palindrome, METH_VARARGS, Detect palindromes},{ NULL, NULL, 0, NULL} }; static struct PyModuleDef palindrome { PyModuleDef_HEAD_INIT, palindrome, /* 模块名 */ , /* 文档字符串 */ -1, /*存储在全局变量中的信号状态 */ PalindromeMethods }; /* 初始化模块的函数*/ PyMODINIT_FUNC PyInit_palindrome(void) { return PyModule_Create(palindrome); }小结概念描述扩展理念Python 扩展的主要用途有两个——利用既有遗留代码和提高瓶颈部分的速度。从头开始编写代码时请尝试使用 Python 建立原型找出其中的瓶颈并在需要时使用扩展来替换它们。预先将潜在的瓶颈封装起来大有裨益。Jython 和 IronPython对这些 Python 实现进行扩展很容易使用底层语言对于 Jython为 Java对于 IronPython为 C#和其他.NET 语言以库的方式实现扩展后就可在 Python 中使用它们了。扩展方法有很多用于扩展代码或提高其速度的工具有的让你更轻松地在 Python 程序中嵌入 C 语言代码有的可提高数字数组操作等常见运算的速度有的可提高 Python 本身的速度。这样的工具包括 SWIG、Cython、Weave、NumPy、ctypes 和 subprocess。SWIGSWIG 是一款自动为 C 语言库生成包装代码的工具。包装代码自动处理 Python CAPI使你不必自己去做这样的工作。使用 SWIG 是最简单、最流行的扩展 Python 的方式之一。使用 Python/C API可手工编写可作为共享库直接导入到 Python 中的 C 语言代码。为此必须遵循 Python/C API对于每个函数你都需要负责完成引用计数、提取参数以及创建返回值等工作另外还需编写将 C 语言库转换为模块的代码包括列出模块中的函数以及创建模块初始化函数。本章介绍的新函数函数描述Py_INCREF(obj)将 obj 的引用计数加 1Py_DECREF(obj)将 obj 的引用计数减 1PyArg_ParseTuple(args, fmt, …)提取位置参数PyArg_ParseTupleAndKeywords(args, kws, fmt, kwlist)提取位置参数和关键字参数PyBuildValue(fmt, value)根据 C 语言值创建 PyObject