我有一个带有枚举的c ++类,我想模仿它boost::python,以便我可以用MyClass.valuepython 编写.boost::python::class_没有enum_方法,我正在寻找解决方法.
我第一次尝试使用lambdas
MyClass{
enum{value1,value2};
};
class_<MyClass>("MyClass").add_property("value1",&[](){return value1;}).staticmethod("value1");
Run Code Online (Sandbox Code Playgroud)
这给出了编译器错误(in get_signaturefor add_property).我知道我可以为每个值创建getter方法,但这对我来说似乎很尴尬(打字方式).
使用attr:
auto classObj=class_<MyClass>("MyClass");
classObj.attr("value1")=(int)value1;
classObj.attr("value2")=(int)value2;
Run Code Online (Sandbox Code Playgroud)
但它不能像.def其他方法一样链接返回对实例的引用.
有更优雅的解决方案吗?
我有一系列的C++结构,我试图用boost python包装.当这些结构包含数组时,我遇到了困难.我试图以最小的开销执行此操作,不幸的是我无法对结构本身进行任何修改.所以比如说我有
struct Foo
{
int vals[3];
};
Run Code Online (Sandbox Code Playgroud)
我希望能够在python中访问它,如下所示:
f = Foo()
f.vals[0] = 10
print f.vals[0]
Run Code Online (Sandbox Code Playgroud)
现在我正在使用一系列get/set函数,但这些函数非常不优雅且与访问其他非数组成员不一致.这是我目前的解决方案:
int getVals (Foo f, int index) { return f.vals[index]; }
void setVals (Foo& f, int index, int value) { f.vals[index] = value; }
boost::python::class_< Foo > ( "Foo", init<>() )
.def ( "getVals", &getVals )
.def ( "setVals", &setVals );
Run Code Online (Sandbox Code Playgroud)
我可以使用get/set函数(因为在某些情况下我需要实现自定义get或set操作)但是我不确定如何合并[]运算符来访问数组的元素.在其他可以使用[]运算符访问的类中,我已经能够使用_ getitem _和_ setitem _这些已经完美地运行了,但是我不知道如果可能的话我会如何对类成员执行此操作.
更新2:我不确定为什么这仍然被投票(2014年3月).自从我多年前提出这个问题以来,这似乎是固定的.确保您使用的是最新版本的boost.
更新:可能需要初始化C++流以格式化数字,并且在Python中加载共享库时不会进行初始化?
我在打电话
cout << 1 << "!" << endl;
Run Code Online (Sandbox Code Playgroud)
在通过boost.python导出到共享库的方法中.它不打印任何东西,但如果我这样做
cout << "%" << "!" << endl;
Run Code Online (Sandbox Code Playgroud)
有用.
这很重要因为我想这样做:
ostream& operator <<(ostream &os, const Bernoulli& b) {
ostringstream oss;
oss << b.p() * 100.0 << "%";
return os << oss.str();
}
Run Code Online (Sandbox Code Playgroud)
通过这样做我暴露了:
BOOST_PYTHON_MODULE(libdistributions)
{
class_<Bernoulli>("Bernoulli")
.def(init<>())
.def(init<double>())
.def("p", &Bernoulli::p)
.def("set_p", &Bernoulli::set_p)
.def("not_p", &Bernoulli::not_p)
.def("Entropy", &Bernoulli::Entropy)
.def("KL", &Bernoulli::KL)
.def(self_ns::str(self))
;
}
Run Code Online (Sandbox Code Playgroud)
但是当我str在伯努利对象上调用python中的方法时,我什么也得不到.我怀疑更简单的cout问题是相关的.
当我这样做时,代码似乎会崩溃 extract<const char*>("a unicode string")
有谁知道如何解决这个问题?
Python C API具有PyObject *PyType_Type对象,它type与解释器中的对象相同.如果我想在C++中定义一个元类,我如何type在Boost.Python中设置它的基础之一?另外,在C++中定义Python元类时,我应该考虑哪些其他事项?
如果有一个Boost.Python解决方案,这将是理想的.如果没有,使用Python C API(或Boost和C API的组合)的解决方案也是好的.由于我的其他课程都有Boost,所以我宁愿将SWIG作为最后的手段.
注意:这实际上是我正在尝试解决的一个更大问题的一部分,如果您感兴趣,我已经在使用Boost.Python设置包装类的元类时询问过.
我正在使用Boost.Python实现一个Python扩展模块.该模块应该定义自己继承的自定义异常类Exception.我怎么做?
默认情况下,libboostpython.a编译时没有-fPIC.但是我必须创建一个python扩展,它是一个动态库,带有-fPIC静态库的链接.如何libboostpython.a用-fPICfrom 编译静态库()boost.python?
SPOILER:部分解决(见最后).
以下是使用Python嵌入的代码示例:
#include <Python.h>
int main(int argc, char** argv)
{
Py_SetPythonHome(argv[1]);
Py_Initialize();
PyRun_SimpleString("print \"Hello !\"");
Py_Finalize();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用gcc 4.8.5在Linux openSUSE 42.2下工作(但我在使用gcc 4.8.3的openSUSE 13.2或使用gcc 4.4.7的RedHat 6.4时也遇到了同样的问题).
我编译了Python 2.7.9的静态和动态版本(但我在Python 2.7.13中也遇到了同样的问题).
我使用以下命令编译链接到Python静态版本的示例:
g++ hello.cpp -o hello \
-I /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/static/include/python2.7 \
-L /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/static/lib \
-l python2.7 -l pthread -l util -l dl
Run Code Online (Sandbox Code Playgroud)
如果我在参数中使用静态版本的Python执行我的示例,它就可以工作.
如果我在参数的动态版本的Python上执行它,我会收到以下错误(它发生在Py_Initialize()):
> ./hello /home/caduchon/softs/python/2.7.9/64/gcc/4.8.5/dynamic
Fatal Python error: PyThreadState_Get: no current thread
Aborted (core dumped)
Run Code Online (Sandbox Code Playgroud)
我不知道为什么它适用于静态版本,它不适用于动态版本.我该如何解决这类问题?
编辑:我安装Python的脚本如下:
#!/bin/bash
WORKDIR=/home/caduchon/tmp/install_python_2_7_13
ARCHIVEDIR=/home/caduchon/downloads/python
PYTHON_VERSION='2.7.13'
EZ_SETUP_VERSION='0.9'
SETUPTOOLS_VERSION='34.1.0'
CYTHON_VERSION='0.25.2'
NUMPY_VERSION='1.12.0'
SCIPY_VERSION='0.18.1' …Run Code Online (Sandbox Code Playgroud) 我有一个带有此签名的python函数:
def post_message(self, message, *args, **kwargs):
Run Code Online (Sandbox Code Playgroud)
我想从c ++调用函数并传递给它一些kwargs.调用函数不是问题.知道如何通过kwargs是.这是一个非工作的释义样本:
std::string message("aMessage");
boost::python::list arguments;
arguments.append("1");
boost::python::dict options;
options["source"] = "cpp";
boost::python::object python_func = get_python_func_of_wrapped_object()
python_func(message, arguments, options)
Run Code Online (Sandbox Code Playgroud)
当我运用这段代码时,在pdb中我得到了(这不是我想要的):
messsage = aMessage
args = (['1'], {'source': 'cpp'})
kwargs = {}
Run Code Online (Sandbox Code Playgroud)
你如何在我的例子中传递**kwargs字典中的选项?
我看过一篇建议使用**选项语法的帖子(这有多酷!):
python_func(message, arguments, **options)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这导致了
TypeError: No to_python (by-value) converter found for C++ type: class boost::python::detail::kwds_proxy
Run Code Online (Sandbox Code Playgroud)
感谢您提供任何帮助.
我有使用两个64位浮点数(两双类模拟128bit的浮筒的自定义浮点数据类型dd_real从QD库).从C++我想导出一个ndarray到python.我已经知道如何为64位浮点数做这个,但是对于双倍的我需要指定我自己的自定义dtype.怎么做?
注意:numpy有自己的128位浮点数(np.float128),遗憾的是它映射到long doubleC/C++,它只是一个存储在128位(在我所有平台上)的80位浮点数.
实际上,应该能够以与numpy导出np.float128(我只是不知道如何完成)相同的方式完成此操作,唯一的区别是它dd_real在C++端使用而不是long double.
如果这有帮助,我已经将C++类型导出dd_real到python使用boost::python也许这可以以某种方式重用.
到目前为止,我能够研究以下内容