繁体   English   中英

如何将c-api扩展嵌套在Python模块中并在该模块中使用它们?

[英]How to nest c-api extensions in a Python module and use them in that module?

我想创建一个名为“ mypack”的Python 3程序包,可以通过pip进行安装。 它具有一些c扩展名和一些调用这些扩展名的python代码。 这是我的目录结构:

setup.py
mypack/__init__.py
mypack/mypack.py
foopkg/foo.cpp

setup.py文件具有以下代码:

from setuptools import setup, Extension

PACKAGE_NAME = 'mypack'

module = Extension('foo',
                language = "c++",
                sources = ['foopkg/foo.cpp'])

setup(name=PACKAGE_NAME,
      version='1.0',
      packages=[PACKAGE_NAME],
      ext_package=PACKAGE_NAME,
      ext_modules=[module],
      include_package_data=True)

我从另一个相关问题改编了此代码,在该问题中,用户希望像mypack.xxx这样导入扩展名,就像我一样。 在c-api扩展中,我已经成功地对其进行了编译,并使它可以作为独立的扩展模块使用,但是在将其合并到较大的程序包中时遇到了麻烦。 它定义了两个函数make_arrayprint_array 为了简洁起见,我删除了功能代码,只包含了Python需要的内容:

...

static PyMethodDef FooMethods[] = {
    { "make_array", make_array, METH_VARARGS, "Put number in array"},
    { "print_array", print_array, METH_VARARGS, "Print number from array"},
    { NULL, NULL, 0, NULL}
};

static struct PyModuleDef foomodule = {
    PyModuleDef_HEAD_INIT,
    "foo",
    "Make/Print array",
    -1,
    FooMethods
};

PyMODINIT_FUNC PyInit_foo(void)
{
    return PyModule_Create(&foomodule);
}

我希望能够在包中导入此扩展名以使用它(这是mypack.py ):

import mypack.make_array
import mypack.print_array

def dostuff():
    array = make_array(10)
    print_array(array)

最后,我的__init__.py文件包含from .mypack import dostuff文件。

然而,当我安装与点子,并尝试运行测试脚本,进口mypack它抱怨在进口mypack.py ,不管我用foo.xxmypack.xx 我使用嵌套结构构建了其他软件包,这些软件包使用__init__.py和导入功能使用模块中其他python文件的代码。 但是我对如何使用c扩展名感到困惑。

从C编译模块的事实与编写import语句的方式没有区别。 线...

import mypack.make_array

尝试导入在名为“ mypack”的程序包中找到的名为“ make_array”的模块。 那不是你所拥有的。 您在名为“ mypack”的程序包中有一个名为“ foo”的模块,并且在该模块中有两个名为“ make_array”和“ print_array”的对象(方法)。

如果从__init__.py删除所有内容并使其以这种方式工作,则要简单得多。 如果您想改善import语句的语法,可以稍后将内容添加到init文件中。 你要...

from mypack.foo import make_array, print_array

要么

import mypack.foo as MYPACK

在第一种情况下,这些方法现在位于全局名称空间中。 在第二种情况下,您可以使用MYPACK.make_arrayMYPACK.print_array访问它们。

我也看到命名您的C扩展名文件mypack和命名您的python文件mypack.py 包中只能有一个具有该名称的模块。 一种解决方案是在C文件名前加下划线。 然后例如在mypack.py中编写...

from ._mypack import make_array

这会将make_array放入myarray的命名空间中,并且客户端代码不必知道或不在乎它是用C编写的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM