如何导入 pybind11 生成的二进制模块?
How to import a binary module generated by pybind11?
我第一次尝试按照 tutorial documentation.
使用 pybind11
如文档所述,我创建了以下 example.cpp
文件,其中包含以下内容:
#include <pybind11/pybind11.h>
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
}
因为我在 macOS 上,基于 this tutorial,我使用以下命令编译了示例文件:(不确定这是否正确但似乎有效)
c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup -I /usr/local/Cellar/pybind11/2.4.3/include example.cpp -o example`python3-config --extension-suffix --includes`
此命令在同一目录中生成 example.cpython-37m-darwin.so
文件。
然后我创建了 example.py
,内容如下:
import example
example.add(1, 2)
但是当我 运行 带有 python example.py
的脚本时,它显示以下错误:
Traceback (most recent call last):
File "example.py", line 1, in <module>
import example
File "/Users/cuinjune/pybind11/build/example.py", line 2, in <module>
example.add(1, 2)
AttributeError: 'module' object has no attribute 'add'
出了什么问题,如何解决?
编辑:以前,它以某种方式生成了 example.pyc
文件,但我不知道该文件是如何生成的,现在它只是说:ImportError: No module named example
.
这一行:
/Users/cuinjune/pybind11/build/example.py
说在你的工作目录中有(或曾经有)另一个文件(或者 /Users/cuinjune/pybind11/build
在你的 PYTHONPATH
中)是一个纯 Python 文件,与你建造的 example.cpython-37m-darwin.so
。当导入 example.py
时,大概是在过去的某个时间,生成了您看到的 example.pyc
。 .pyc
保持完整的独立功能,即使原始 example.py
已被删除。 .pyc
文件将在其中硬编码原始文件的完整目录,因此将继续引用该文件,即使它已被删除。
根据你的更新,现在所有其他 example.py
、.pyc
、.pyo
都消失了,对吗?
首先确保您 python 的解释器 运行 与您用来构建的标签相匹配。例如 运行:
python3 -c 'import distutils.sysconfig as ds; print(ds.get_config_var("EXT_SUFFIX"))'
(我假设您使用 python3
作为启动 Python 解释器的命令;如果没有,则将其更改为相关命令)。
其次,验证 PYTHONPATH
envar 以查看本地目录(完整拼写或 .
)是否在其中。如果没有,请添加。
有了这两个,应该可以了...
然而,就我个人而言,我首先会通过将模块重命名为更独特的东西来简化我的生活(重命名 .cpp
中的 example
以及 CLI 中的目标)。
我第一次尝试按照 tutorial documentation.
使用 pybind11如文档所述,我创建了以下 example.cpp
文件,其中包含以下内容:
#include <pybind11/pybind11.h>
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
}
因为我在 macOS 上,基于 this tutorial,我使用以下命令编译了示例文件:(不确定这是否正确但似乎有效)
c++ -O3 -Wall -shared -std=c++11 -undefined dynamic_lookup -I /usr/local/Cellar/pybind11/2.4.3/include example.cpp -o example`python3-config --extension-suffix --includes`
此命令在同一目录中生成 example.cpython-37m-darwin.so
文件。
然后我创建了 example.py
,内容如下:
import example
example.add(1, 2)
但是当我 运行 带有 python example.py
的脚本时,它显示以下错误:
Traceback (most recent call last):
File "example.py", line 1, in <module>
import example
File "/Users/cuinjune/pybind11/build/example.py", line 2, in <module>
example.add(1, 2)
AttributeError: 'module' object has no attribute 'add'
出了什么问题,如何解决?
编辑:以前,它以某种方式生成了 example.pyc
文件,但我不知道该文件是如何生成的,现在它只是说:ImportError: No module named example
.
这一行:
/Users/cuinjune/pybind11/build/example.py
说在你的工作目录中有(或曾经有)另一个文件(或者 /Users/cuinjune/pybind11/build
在你的 PYTHONPATH
中)是一个纯 Python 文件,与你建造的 example.cpython-37m-darwin.so
。当导入 example.py
时,大概是在过去的某个时间,生成了您看到的 example.pyc
。 .pyc
保持完整的独立功能,即使原始 example.py
已被删除。 .pyc
文件将在其中硬编码原始文件的完整目录,因此将继续引用该文件,即使它已被删除。
根据你的更新,现在所有其他 example.py
、.pyc
、.pyo
都消失了,对吗?
首先确保您 python 的解释器 运行 与您用来构建的标签相匹配。例如 运行:
python3 -c 'import distutils.sysconfig as ds; print(ds.get_config_var("EXT_SUFFIX"))'
(我假设您使用 python3
作为启动 Python 解释器的命令;如果没有,则将其更改为相关命令)。
其次,验证 PYTHONPATH
envar 以查看本地目录(完整拼写或 .
)是否在其中。如果没有,请添加。
有了这两个,应该可以了...
然而,就我个人而言,我首先会通过将模块重命名为更独特的东西来简化我的生活(重命名 .cpp
中的 example
以及 CLI 中的目标)。