给出一个类:
class TCurrency {
TCurrency();
TCurrency(long);
TCurrency(const std::string);
...
};
Run Code Online (Sandbox Code Playgroud)
用Boost.Python包装:
class_<TCurrency>( "TCurrency" )
.def( init<long> )
.def( init<const std::string&> )
...
;
Run Code Online (Sandbox Code Playgroud)
是否可以创建在Python中显示为构造函数的工厂方法:
TCurrency TCurrency_from_Foo( const Foo& ) { return TCurrency(); }
Run Code Online (Sandbox Code Playgroud)
这样在python中:
bar = TCurrency(foo)
Run Code Online (Sandbox Code Playgroud) 我无法弄清楚为什么这个程序失败了.
#!/usr/bin/env python
from __future__ import division, print_function
from future_builtins import *
import types
import libui as ui
from PyQt4 import QtCore
import sip
p = ui.QPoint()
q = QtCore.QPoint()
def _q_getattr(self, attr):
print("get %s" % attr)
value = getattr(sip.wrapinstance(self.myself(), QtCore.QPoint), attr)
print("get2 %s returned %s" % (attr, value))
return value
p.__getattr__ = types.MethodType(_q_getattr, p)
print(p.__getattr__('x')()) # Works! Prints "0"
print(p.x()) # AttributeError: 'QPoint' object has no attribute 'x'
Run Code Online (Sandbox Code Playgroud)
我使用Boost.Python来创建libui,它暴露了类QPoint.我包括PyQt4,它有一个sip暴露的QPoint.我正在尝试完成两种类型之间的映射.
我检查过这p是一个新式的课程,为什么不__getattr__被要求p.x()?
我正在尝试使用Boost.Python将ac库包装在高级python接口中.c库的一个客户端契约是其中一个句柄每个进程只能分配一次.我希望我可以通过使用全局模块在python端强制执行此合同.
这是我的django组件模块__init__.py.PyGenTL每个进程只能创建一次!
import my_c_mod
import os
print "imager__init__()"
print os.getpid()
ptl = my_c_mod.PyGenTL()
Run Code Online (Sandbox Code Playgroud)
稍微相关的Boost.Python代码
BOOST_PYTHON_MODULE(my_c_mod)
{
using namespace boost::python;
// Create the Python type object for our extension class and define __init__ function.
class_<PyGenTL>("PyGenTL")
.def("sys_info", &PyGenTL::SysInfo)
.def("list_cameras", &PyGenTL::ListCameras) //
.def("start_camera", &PyGenTL::StartCamera) //
;
}
PyGenTL::PyGenTL()
{
try {
std::cout << "PyGenTL ctor(): allocating GenTL Lib." << std::endl;
Detail::ThrowError(GCInitLib());
Detail::ThrowError(TLOpen(&hTL));
} catch (boost::exception& e) {
std::cerr << "PyGenTL ERROR! ";
std::cerr << boost::diagnostic_information(e);
std::cerr << std::endl;
} …Run Code Online (Sandbox Code Playgroud) 我得到一个错误,我无法通过Boost.Python包装一个相当简单的c ++类.一,班级:
#include <boost/python.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <string>
class token {
public:
typedef boost::shared_ptr<token> ptr_type;
static std::vector<std::string> empty_context;
static std::string empty_center;
token(std::string& t = empty_center,
std::vector<std::string>& left = empty_context,
std::vector<std::string>& right = empty_context)
: center(t), left_context(left), right_context(right) {}
virtual ~token(void) {}
std::vector<std::string> left_context;
std::vector<std::string> right_context;
std::string center;
};
std::string token::empty_center;
std::vector<std::string> token::empty_context;
Run Code Online (Sandbox Code Playgroud)
暴露于python via
BOOST_PYTHON_MODULE(test) {
namespace bp = boost::python;
bp::class_<token, token::ptr_type>("token")
.def(bp::init<std::string&, bp::optional<std::vector<std::string>&,
std::vector<std::string>&> >())
;
}
Run Code Online (Sandbox Code Playgroud)
然后,当试图在python中使用它时:
Python 2.7.2 (default, Aug 19 2011, 20:41:43) [GCC] on …Run Code Online (Sandbox Code Playgroud) 我正在研究一个我正在尝试使用boost python的项目.在研究如何组织我的python接口时,我遇到了一个注释,声称存在boost python的性能问题.它的性能是否有任何实际问题?
在这种情况下,我正在使用一个大型项目,我们希望将其中的一些暴露给python.我发现boost python可以很容易地暴露我已经拥有的类.所以我更喜欢使用boost python的暴露类的方法,因为它很容易.除非有人有一个易于使用和高效的替代方案.
我有一个用C ++编写的内部库,目前正在研究将其扩展到Python中。我在开始时就考虑了Boost.Python,但是我愿意接受其他选择。
当前,我有一个C ++函数,需要接受一个Python类实例,然后使用该对象的方法执行某些任务。这个想法是让Python用户永远不需要处理C ++。期望他们从我将提供的Python模板/示例类中创建此Python对象,并使用我可以假设在C ++库中存在的预设方法名称。
暴露给Python用户的界面如下所示:
class Foo(object):
def __init__(self, args):
"""create an instance of this class with instance-specific attributes"""
def Bar1(self, a, b, c):
"""do something with the given integers a, b and c"""
pass
def Bar2(self, a, b, c):
"""do something else with the given integers a, b and c"""
pass
import mylib
cheese = mylib.Wine()
cheese.do_something(Foo)
Run Code Online (Sandbox Code Playgroud)
在C ++中,相应的代码如下所示:
#include <boost/python.h>
#include <Python.h>
class Wine {
public:
Wine() {};
~Wine() {};
static void do_something(boost::python::object *Foo) {
int …Run Code Online (Sandbox Code Playgroud) 我想包装一个返回一个的函数boost::optional<T>.那是,给定:
class Foo {
boost::optional<T> func();
};
Run Code Online (Sandbox Code Playgroud)
我想以某种方式包装它以便Python获得一个Tby值,或者None:
class_<Foo>("Foo")
.def("func", func, return_value_policy<return_boost_optional???>);
Run Code Online (Sandbox Code Playgroud)
通常,如果它刚刚返回T,我可以使用:
class_<Foo>("Foo")
.def("func", func, return_value_policy<return_by_value>());
Run Code Online (Sandbox Code Playgroud)
但是既然它返回了一个boost::optional<T>,它也可以返回boost::none,我想最终成为Python的None.
有没有办法用现有的转换器做到这一点?如果没有,是否有一些解决方法可以达到同样的效果?
有关MacOSX Yosemite上Homebrew和pyenv共存的几个新手问题。在将我的google-fu水平应用于该主题之后,我仍然感到困惑。抱歉,长度不够,但我想尽可能清楚。
首先,一些背景。我用brew安装pyenv,然后用pyenv安装python2和python3。
brew install pyenv
brew install pyenv-virtualenv
*I also added the necessary hooks into my profiles.*
pyenv install 2.7.10
pyenv install 3.4.3
pyenv rehash
pyenv global 2.7.10
Run Code Online (Sandbox Code Playgroud)
??? 问题(或澄清)。如果brew使用的是pyenv安装的python,我认为这会被皱眉,因为brew软件包将依赖于brew之外的东西来构建(例如,使用pyenv卸载python版本可能会破坏brew软件包)?看来brew使用PATH中第一个出现的python(对我来说是pyenv的版本)?但是,在以下每种情况下,填充都是针对“ python”而不是“ python3”的(甚至对于pyenv 3.4.3)。我是否假设设置“ pyenv shell 3.4.3”将使brew brew python命令(假设适用于python2.x)正确到pyenv的python 3.4.3,这是我正确的做法吗?
pyenv shell 2.7.10
brew --config
Python: /Users/anonymous/.pyenv/shims/python => /Users/anonymous/.pyenv/versions/2.7.10/bin/python2.7
pyenv shell 3.4.3
brew --config
Python: /Users/anonymous/.pyenv/shims/python => /Users/anonymous/.pyenv/versions/3.4.3/bin/python3.4
pyenv shell system
brew --config
Python: /Users/anonymous/.pyenv/shims/python => /usr/bin/python
Run Code Online (Sandbox Code Playgroud)
??? 题。如果使用pyenv的python进行酿造不是一个好主意,那么我是否也应该安装python和python3的酿造版本,否则会发生冲突并以某种方式引起问题吗?我的选择似乎是使用在我的Mac上安装的系统python,还是使用brew自己的pythons满足我的所有酿造需求。在第一种情况下,我可以确保在任何酝酿之前调用“ pyenv shell系统”,或者设置别名以按照其他人的建议使它自动化(alias brew =“ …
我有一个应用程序,实现python解释器,自定义python模块,导出类.示例c ++类可能如下所示:
class MyClass {
MyClass() { cout << "created" << endl; }
~MyClass() { cout << "destroyed" << endl; }
};
Run Code Online (Sandbox Code Playgroud)
执行python脚本的代码如下所示:
namespace bp = boost::python;
bp::dict dict;
try {
dict = bp::dict(bp::import("__main__").attr("__dict__"));
bp::exec_file(filename, dict, dict);
} catch (bp::error_already_set &) {
// dict.clear()
PyErr_Print();
PyErr_Clear();
}
Run Code Online (Sandbox Code Playgroud)
问题是,在脚本被异常终止后,不会立即销毁从python代码创建的c ++对象.例如,简单的脚本运行两次:
import MyModule
myobj = MyModule.MyClass()
assert False
Run Code Online (Sandbox Code Playgroud)
输出我得到(A):
// script launched first time
created
// script finished
// script launched second time
created
destroyed
// script finished
// Py_Finalize() …Run Code Online (Sandbox Code Playgroud) boost-python ×10
python ×6
c++ ×4
boost ×2
constructor ×1
django ×1
factory ×1
homebrew ×1
pyenv ×1
pyqt ×1
python-3.x ×1
python-sip ×1
wrapper ×1