我在这里找到了文档,邮件列表和这个问题之间的部分答案,但我希望得到更直接的答案来解决我的具体问题......
我正在学习cython,试图一点一点地包装我已经使用的库,当前包含在boost :: python中的库.我为这个boost包装器贡献了一点点,并将它用作c ++参考,同时我使用ZeroMQ Python绑定作为cython参考.
我的问题是关于项目结构.这个lib的当前boost版本编译为单个.so,这是我的目标.我很快发现你不能直接将多个.pyx模块编译成一个.so.然后我开始沿着定义文件中的cppclass's' pxd及其相应的python导出的实现类的路径.pxi,并试图将它们包含在单个文件中pyx进行编译.虽然它最初起作用,但是一旦我写了一点,我就会因为pxi包含在不同的地方而遇到多个定义冲突的问题.
我很想听到一个适当的组织方法来解决以下问题和目标:
cppclass(我现在通过将cppclass放在不同的命名中pyd并使用导入的命名空间来处理类似的名称,ala 使用cimport来解决命名冲突).so作为编译输出(可接受的方法?)pyx多包含方法进入主要方法pyx,还是主要pyx包含除了包含包含之外的其他内容?src放在我的下面一个大目录中setup.py.看到这么多pxi, pxd, pyx文件会让人感到困惑.pxi现在完全没有必要?如果没有,我是否需要使用cython风格的ifndef防护来处理不同模块之间的多个包含?__init__.py.这真的是cython的正确方法吗?作为参考,我正在练习重新包装的项目是PyOpenNI(openni).此boost项目采用的模式是在一个地方收集公共对象,然后使用源定义一对一的头定义,然后有一个巨大的包装器将所有定义收集到单个位置.还有添加的自定义异常处理和实用程序.
我有多个.pyx文件,有没有办法将它们导入单个pyx文件并将该文件编译成共享库,而不必编译15个独立模块?
我正在尝试从 python 源文件创建一个 unix 可执行文件。
我有两个文件,p1.py并且p2.py
p1.py:-
from p2 import test_func
print (test_func())
Run Code Online (Sandbox Code Playgroud)
p2.py:-
def test_func():
return ('Test')
Run Code Online (Sandbox Code Playgroud)
现在,正如我们所看到的,p1.py依赖于p2.py. 我想通过将两个文件组合在一起来制作一个可执行文件。我正在使用 cython。
我将文件名分别更改为p1.pyx和p2.pyx。
现在,我可以使用 cython 使文件可执行,
cython p1.pyx --embed
Run Code Online (Sandbox Code Playgroud)
它将生成一个名为 .c 的 C 源文件p1.c。接下来我们可以使用 gcc 使其可执行,
gcc -Os -I /usr/include/python3.5m -o test p1.c -lpython3.5m -lpthread -lm -lutil -ldl
Run Code Online (Sandbox Code Playgroud)
但是如何将两个文件合并为一个可执行文件呢?
我正在尝试在C程序中调用cython(cdef)函数。当cdef函数包含python语句(例如print(0.5)或python(def)函数)时,调用(cdef)函数会引发分段错误。
.pyx文件:
# cython: language_level=3
cdef public double PI = 3.1415926
cdef public double get_e():
print("calling get_e()")
return 2.718281828
Run Code Online (Sandbox Code Playgroud)
.c文件:
#include "Python.h"
#include "transcendentals.h"
#include <math.h>
#include <stdio.h>
int main(int argc, char **argv) {
Py_Initialize();
PyInit_transcendentals();
printf("pi**e: %f\n", pow(PI, get_e()));
Py_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译命令:
cython transcendentals.pyx
gcc -I. -I/usr/include/python3.5m -I/usr/include/python3.5m \
-Wno-unused-result -Wsign-compare \
-g -fstack-protector-strong -Wformat \
-Werror=format-security -DNDEBUG -g \
-fwrapv -O3 -Wall -Wstrict-prototypes \
-L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu \
-L/usr/lib transcendentals.c main.c \
-lpython3.5m -lpthread -ldl -lutil -lm -Xlinker …Run Code Online (Sandbox Code Playgroud) 我有一个用 C 编写的 python 模块,它有一个主模块和一个子模块(名称带点,不确定这是否可以称为真正的子模块):
PyMODINIT_FUNC initsysipc(void) {
PyObject *module = Py_InitModule3("sysipc", ...);
...
init_sysipc_light();
}
static PyTypeObject FooType = { ... };
PyMODINIT_FUNC init_sysipc_light(void) {
PyObject *module = Py_InitModule3("sysipc.light", ...);
...
PyType_Ready(&FooType);
PyModule_AddObject(module, "FooType", &FooType);
}
Run Code Online (Sandbox Code Playgroud)
该模块被编译为sysipc.so,当我将它放在当前目录中时,以下导入工作没有问题:
import sysipc
import sysipc.light
from sysipc.light import FooType
Run Code Online (Sandbox Code Playgroud)
问题是我想把这个模块放在一个命名空间包中,文件夹结构是这样的:
company/
company/__init__.py
company/dept/
company/dept/__init__.py
company/dept/sys/
company/dept/sys/__init__.py
company/dept/sys/sysipc.so
Run Code Online (Sandbox Code Playgroud)
所有三个__init__.py只包括标准setuptool导入行:
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
Run Code Online (Sandbox Code Playgroud)
在当前目录中,以下导入不起作用:
from company.dept.sys import sysipc;
from company.dept.sys.sysipc.light import FooType;
Run Code Online (Sandbox Code Playgroud)
sysipc.light在这种情况下,我应该如何导入模块中定义的类型和方法?
====================================
更新实际错误:
我已经sysipc.so …