我有以下boost python代码:
#include <boost/python.hpp>
namespace bp = boost::python;
class PyExtTest
{
public:
std::string get_name() { return m_name; }
void set_name(std::string const& name) { m_name = name; }
private:
std::string m_name;
};
BOOST_PYTHON_MODULE(test_ext)
{
bp::class_<PyExtTest>("pet")
.add_property("name", &PyExtTest::get_name, &PyExtTest::set_name)
;
}
使用distutils将其编译成以下目录层次结构:
build/lib/test_ext.so
然后按如下方式使用( PYTHONPATH
设置为build/lib
):
import test_ext
a = test_ext.pet
a.name = 'dog'
print a.name # dog
当我将distutils配置为将test_ext
作为包pkg
的一部分安装时,python将无法再找到该模块。我以目录层次结构结束:
build/lib/pkg
build/lib/pkg/__init__.py
build/lib/pkg/test_ext.so
使用安装脚本,如下所示:
test_module = Extension('pkg.test_ext'
, define_macros = module_macros
, extra_compile_args = module_compiler_flags
, sources = ['pkg/test_ext/test.cpp']
, include_dirs = module_include_dirs
, library_dirs = module_lib_dirs
, libraries = module_libs)
setup (name = 'Test'
, version = '0.1'
, description = 'Test'
, packages = ['pkg']
, ext_modules = [test_module])
但是试图导入模块:
import pkg.test_ext
结果出现错误:
ImportError: No module named test_ext
如果我用一个纯python模块来代替test_ext
,那么一切都如预期的那样工作。
我认为我需要以某种方式更改boost代码,以表明test_ext
扩展位于pkg
包中,但我无法确切地知道如何做到这一点。
我尝试将test_ext.so
移动到build/lib
目录层次结构中的正确位置,以获得我想要的包布局,但是它被识别为模块的唯一位置是直接在build/lib
下面。这与.py
文件不同,我可以从目录层次结构中的任何位置成功地导入它们。
我正在使用python 2.7.6
和boost 1.55
。
任何帮助都是非常感谢的。
发布于 2014-01-03 14:09:02
如Boost.Python Creating Packages
教程所示,在导入纯python模块和python扩展模块之间没有什么特殊要求。
给定以下目录结构,其中src/pkg/__init__.py
为空,src/test_ext/test_ext.cpp
包含问题中发布的Boost.Python代码:
.
|-- setup.py
'-- src
|-- pkg
| '-- __init__.py
'-- test_ext
└'-- test_ext.cpp
下面的setup.py
文件包含特定于我的环境的路径:
from distutils.core import setup, Extension
test_module = Extension('pkg.test_ext',
sources=['src/test_ext/test_ext.cpp'],
include_dirs=['/usr/local/include'],
library_dirs=['/usr/local/lib/boost'],
runtime_library_dirs=['/usr/local/lib/boost'],
libraries=['boost_python'])
setup(name='Test',
version='0.1',
description='Test',
package_dir={'': 'src'},
packages=['pkg'],
ext_modules=[test_module])
python setup.py build
命令生成以下目录树:
.
|-- build
¦ |-- lib.linux-i686-2.7
¦ ¦ '-- pkg
¦ ¦ |-- __init__.py
¦ ¦ '-- test_ext.so
¦ '-- temp.linux-i686-2.7
¦ '-- src
¦ '-- test_ext
¦ '-- test_ext.o
|-- setup.py
'-- src
|-- pkg
¦ '-- __init__.py
'-- test_ext
'-- test_ext.cpp
pkg.text_ext
模块可以通过将build/lib.linux-i686-2.7
目录路径添加到模块搜索路径来导入。例如,将路径附加到:
PYTHONPATH
环境变量sys.path
列表。在本例中,我选择从包含build
的目录启动解释器,并将build/lib.linux-i686-2.7
附加到sys.path
。
>>> import sys
>>> sys.path.append('build/lib.linux-i686-2.7')
>>> import pkg.test_ext
>>> parrot = pkg.test_ext.pet()
>>> parrot
<pkg.test_ext.pet object at 0xb7439a7c>
>>> parrot.name = 'Polly'
>>> print parrot.name
Polly
如果导入模块时仍然发生故障,那么考虑使用-vv
参数运行python。这将导致python为导入时选中的每个文件打印详细的跟踪消息。观察Python在何处搜索和查找pkg
包,但未能找到test_ext
模块可能会有所帮助。例如,如果我从src
目录中启动Python解释器:
src$ python -vv
# ... some python loading verbose tracing ...
>>> import
# ... get the verbose tracing for the imports import needs out of the way...
File "<stdin>", line 1
import
^
SyntaxError: invalid syntax
>>> import pkg.test_ext
import pkg # directory pkg
# trying pkg/__init__.i386-linux-gnu.so
# trying pkg/__init__.so
# trying pkg/__init__module.so
# trying pkg/__init__.py
import pkg # from pkg/__init__.py
# wrote pkg/__init__.pyc
# trying pkg/test_ext.i386-linux-gnu.so
# trying pkg/test_ext.so
# trying pkg/test_extmodule.so
# trying pkg/test_ext.py
# trying pkg/test_ext.pyc
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named test_ext
可以看到,pkg
包是相对于我当前的工作目录找到的,但是在尝试了各种扩展之后,它没有找到test_ext
模块。
https://stackoverflow.com/questions/20872698
复制