如何扩展NumPy(电脑如何扩展c盘)

小编:魅力 更新时间:2022-08-22

编写扩展模块

虽然ndarray对象旨在允许在Python中进行快速计算,但它也被设计为通用的并且满足各种各样的计算需求。因此,如果绝对速度是必不可少的,那么就不能替换特定于您的应用程序和硬件的精心编制的循环。这是numpy包含f2py的原因之一,因此可以使用易于使用的机制将(简单的)C / C ++和(任意)Fortran代码直接链接到Python中。我们鼓励您使用和改进此机制。本节的目的不是记录此工具,而是记录编写此工具所依赖的扩展模块的更基本步骤。

当扩展模块被编写,编译并安装到Python路径(sys.path)中的某个位置时,可以将代码导入到Python中,就好像它是标准的python文件一样。它将包含已在C代码中定义和编译的对象和方法。在Python中执行此操作的基本步骤已有详细记录,您可以在www.python.org

上的在线文档中找到更多信息。

除了Python C-API之外,NumPy还有一个完整而丰富的C-API,允许在C级上进行复杂的操作。但是,对于大多数应用程序,通常只使用少量API调用。如果你需要做的就是提取一个指向内存的指针以及一些形状信息以传递给另一个计算例程,那么你将使用非常不同的调用,然后如果你试图创建一个类似于数组的新类型或添加一个新数据ndarrays的类型。本章介绍了最常用的API调用和宏。

必需的子程序

必须在C代码中定义一个函数才能使Python将其用作扩展模块。该函数必须被称为init {name},其中{name}是Python中模块的名称。必须声明此函数,以便对例程外部的代码可见。除了添加您想要的方法和常量之外,此子例程还必须包含调用import_array()
和/或import_ufunc()取决于需要哪个C-API。只要实际调用任何C-API子例程,忘记放置这些命令就会将自身显示为一个丑陋的分段错误(崩溃)。实际上,在单个文件中可以有多个init {name}函数,在这种情况下,该文件将定义多个模块。但是,有一些技巧可以让它正常工作,这里没有涉及。

一个最小的init{name}方法看起来像:

PyMODINIT_FUNCinit{name}(void){ (void)Py_InitModule({name}, mymethods); import_array();}

mymethods必须是PyMethodDef结构的数组(通常是静态声明的),它包含方法名,实际的C函数,指示方法是否使用关键字参数的变量,以及docstrings。这些将在下一节中介绍。如果要向模块添加常量,则存储Py_InitModule的返回值,Py_InitModule是一个模块对象。向模块添加项目的最常用方法是使用PyModule_GetDict(模块)获取模块字典。使用模块字典,您可以手动将任何您喜欢的内容添加到模块中。向模块添加对象的更简单方法是使用三个额外的Python C-API调用之一,这些调用不需要单独提取模块字典。这些内容记录在Python文档中,但为方便起见,在此处重复:

int PyModule_AddObject(PyObject

*module,char *name,PyObject

* value )¶

int PyModule_AddIntConstant(PyObject

* module ,char * name ,long value )¶

int PyModule_AddStringConstant(PyObject

* module ,char * name ,char * value )¶

所有这三个函数都需要 模块 对象(Py_InitModule的返回值)。该 名称 是标签模块中的值的字符串。根据调用的函数, value 参数是一般对象(PyModule_AddObject窃取对它的引用),整数常量或字符串常量。

定义函数

传递给Py_InitModule函数的第二个参数是一个结构,可以很容易地在模块中定义函数。在上面给出的示例中,mymethods结构将在文件的早期(通常在init {name}子例程之前)定义为:


。。。。。。。。。。。。。

作者:柯广

篇幅有限更多请见扩展链接:http://www.mark-to-win.com/tutorial/52203.html