Import and use of user defined python modules
[
Front page
] [
New
|
List of pages
|
Search
|
Recent changes
|
Help
]
Start:
[[SIGVerse with Python]]
The aim of this tutorial is to show:
--how to import a system-define and user-define python mo...
--how to read the values returned by Python modules (e.g....
We saw in the previous tutorial that the "exec" function ...
#highlight(python){{
boost::python("print 'Hello, world'", main_namespace);
boost::python("print 'Hello, world'[3:5]", main_namespace...
boost::python("print '.'.join(['1','2','3'])", main_names...
}}
Of course, we would like to import modules (both user def...
Here, I will show one example of standard module "random"...
#highlight(python){{
boost::python::exec("import random", main_namespace);
boost::python::object rand = boost::python::eval("rand...
std::cout << py::extract<double>(rand) << std::endl
}}
Here we imported the random module by executing the corre...
As suggested in the [[blog:http://thejosephturner.com/blo...
#highlight(python){{
boost::python::object rand_mod = boost::python::impor...
boost::python::object rand_func = rand_mod.attr("rand...
boost::python::object rand2 = rand_func();
std::cout << boost::python::extract(rand2) << std::en...
}}
In the above example, random module is imported, but this...
Now, please copy the following code and name it as "Contr...
The code as following functionalities
--it executes normal, non-imported code
--imports a system defined module "random", call its attr...
--shows an object-oriented way to import a module into Si...
--using a user-defined module called sample.py which ret...
--use of error parsing
#highlight(c){{
#include "ControllerEvent.h"
#include "Controller.h"
#include "Logger.h"
#include <iostream>
#include <boost/python.hpp>
#include <Python.h>
#include <dlfcn.h>
namespace py = boost::python; // create namespace variabl...
using namespace std;
std::string parse_python_exception(); // functional decla...
template <typename T> string tostr(const T& t) { ostrings...
class MyController : public Controller {
public:
void onInit(InitEvent &evt);
double onAction(ActionEvent&);
void onRecvMsg(RecvMsgEvent &evt);
void onCollision(CollisionEvent &evt);
};
void MyController::onInit(InitEvent &evt) {
SimObj *my = getObj(myname());
dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL);
Py_Initialize(); //initialization of the python interp...
}
double MyController::onAction(ActionEvent &evt) {
double x=2.0;
Py_Initialize();
try{
py::object main_module = py::import("__main__");
// load the dictionary object out of the main mod...
py::object main_namespace = main_module.attr("__d...
// run simple code within the main namespace usin...
py::exec("print 'Executing normal, non-imported c...
// function
py::exec("print 'Hello, world'", main_namespace);
// any valid Python will execute
py::exec("print 'Hello, world'[3:5]", main_namesp...
// it is as if you opened a new Python file and w...
// all of the normal functionality is available
py::exec("print '.'.join(['1','2','3'])", main_na...
py::exec("print 'Importing a module that prints r...
// of course, you can also import functionality f...
py::exec("import random", main_namespace);
// boost::python::eval will return the result of ...
// as a boost::python::object
py::object rand = py::eval("random.random()", mai...
// the boost::python::extract function can then c...
// (only as appropriate, of course)
std::cout << py::extract<double>(rand) << std::en...
// or, if you'd prefer, you can extract the func...
// then call them as you wish from C++. this is ...
// of this file. you can't execute code with the...
// extracting the namespace object as we did wit...
// this method ultimately provides a much cleane...
// objects over their lifetimes
py::exec("print 'A more object oriented way to i...
// import the random module
py::object rand_mod = py::import("random");
// extract the random function from the random mo...
py::object rand_func = rand_mod.attr("random");
// call the function and extract the result
// [sidenote: this sort of syntax is what makes ...
py::object rand2 = rand_func();
std::cout << py::extract<double>(rand2) << std::e...
// Here is an example, of reading a list to C++ d...
py::exec("print 'Converting a list to C++ data ty...
py::object randList = py::eval("random.sample(ran...
// call the function and extract the result
// the boost::python::extract function can then r...
// (only as appropriate, of course)
int n = len((randList));
for(unsigned int i=0; i<n; i++){
std::cout << py::extract<double>((randList)[i...
}
// Here is an example, of importing a user define...
// The list is extracted into a C++ Data type.
py::exec("print ' User defined python module that r...
py::object sample_module = py::import("sample");
py::object sample_func = sample_module.attr("...
py::object func_list = sample_func();
int x = len((func_list));
for(unsigned int i=0; i<x; i++){
std::cout << py::extract<double>((func_list)[...
}
}catch(boost::python::error_already_set const &){
// Parse and output the exception
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str <<...
}
return 1.0;
}
void MyController::onRecvMsg(RecvMsgEvent &evt) {
}
void MyController::onCollision(CollisionEvent &evt) {
}
extern "C" Controller * createController() {
return new MyController;
}
std::string parse_python_exception(){
PyObject *type_ptr = NULL, *value_ptr = NULL, *traceb...
// Fetch the exception info from the Python C API
PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr);
// Fallback error
std::string ret("Unfetchable Python error");
// If the fetch got a type pointer, parse the type in...
if(type_ptr != NULL){
py::handle<> h_type(type_ptr);
py::str type_pstr(h_type);
// Extract the string from the boost::python object
py::extract<std::string> e_type_pstr(type_pstr);
// If a valid string extraction is available, use...
// otherwise use fallback
if(e_type_pstr.check())
ret = e_type_pstr();
else
ret = "Unknown exception type";
}
// Do the same for the exception value (the stringifi...
if(value_ptr != NULL){
py::handle<> h_val(value_ptr);
py::str a(h_val);
py::extract<std::string> returned(a);
if(returned.check())
ret += ": " + returned();
else
ret += std::string(": Unparseable Python erro...
}
// Parse lines from the traceback using the Python tr...
if(traceback_ptr != NULL){
py::handle<> h_tb(traceback_ptr);
// Load the traceback module and the format_tb fu...
py::object tb(py::import("traceback"));
py::object fmt_tb(tb.attr("format_tb"));
// Call format_tb to get a list of traceback stri...
py::object tb_list(fmt_tb(h_tb));
// Join the traceback strings into a single string
py::object tb_str(py::str("\n").join(tb_list));
// Extract the string, check the extraction, and ...
py::extract<std::string> returned(tb_str);
if(returned.check())
ret += ": " + returned();
else
ret += std::string(": Unparseable Python trac...
}
return ret;
}
}}
Please set the following environment variables to set the...
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/p...
Now, execute "make" it will create a ControllerSample.so ...
make
Please copy the following xml file and name it as "WorldS...
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld1">
<gravity x="0.0" y="-980.7" z="0.0"/>
<instanciate class="seToy_D.xml">
<set-attr-value name="name" value="toy_D"/>
<set-attr-value name="language" value="c++"/>
<set-attr-value name="implementation"
value="./ControllerSample.so"/>
<set-attr-value name="dynamics" value="true"/>
<set-attr-value name="x" value="0.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="0.0"/>
<set-attr-value name="mass" value="1.0"/>
<set-attr-value name="collision" value="true"/>
</instanciate>
</world>
}}
Please copy the following python file and name it as "sam...
#highlight(python){{
def simpleList():
import numpy
a = numpy.ones((2,4))
a.tolist()
return a.tolist()[0]
}}
Please copy the following Makefile file and name it as "M...
#highlight(c){{
#sigverse header
SIG_SRC = $(SIGVERSE_PATH)/include/sigverse
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/raghav/pool...
CC = gcc
CPP = g++
AS = as
LD = g++
AR = ar
RANLIB = ranlib
OBJCOPY = objcopy
# external libraries and headers
# change the next line to point to the location of your b...
EXTERN_DIR = /home/raghav/pool
EXTERN_LIBDIR = $(EXTERN_DIR)/lib
EXTERN_INCDIR = $(EXTERN_DIR)/include
EXTERN_BINDIR = $(EXTERN_DIR)/bin
BOOST_PYTHON_LIB = $(EXTERN_LIBDIR)/libboost_python.a
INCDIRS = .
INCDIRS += $(EXTERN_INCDIR)
# you may also need to change this directory if you want ...
# python version
INCDIRS += /usr/include/python2.7
INCDIRS += /usr/lib/python2.7/dist-packages/numpy/core/in...
INCDIR = $(foreach dir, $(INCDIRS), -I$(dir))
%.o: %.cpp
$(CPP) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
#specifying of object file
OBJS = ControllerSample.so
ControllerSample.so: ControllerSample.cpp
g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE -I$(S...
#$^ , $+ The names of all the prerequisites, with spa...
# while $+ retains them and preserves their order
clean:
rm -rf *.so *.o $(HWOBJS) hello_world
}}
Also set the PYTHONPATH
export PYTHONPATH=$PYTHONPATH:/path_to_your_work...
Now, please load the world file into Sigverse and push "S...
./sigverse.sh -w ./WorldSample.xml -p your_port_n...
#highlight(end)
#counter
End:
[[SIGVerse with Python]]
The aim of this tutorial is to show:
--how to import a system-define and user-define python mo...
--how to read the values returned by Python modules (e.g....
We saw in the previous tutorial that the "exec" function ...
#highlight(python){{
boost::python("print 'Hello, world'", main_namespace);
boost::python("print 'Hello, world'[3:5]", main_namespace...
boost::python("print '.'.join(['1','2','3'])", main_names...
}}
Of course, we would like to import modules (both user def...
Here, I will show one example of standard module "random"...
#highlight(python){{
boost::python::exec("import random", main_namespace);
boost::python::object rand = boost::python::eval("rand...
std::cout << py::extract<double>(rand) << std::endl
}}
Here we imported the random module by executing the corre...
As suggested in the [[blog:http://thejosephturner.com/blo...
#highlight(python){{
boost::python::object rand_mod = boost::python::impor...
boost::python::object rand_func = rand_mod.attr("rand...
boost::python::object rand2 = rand_func();
std::cout << boost::python::extract(rand2) << std::en...
}}
In the above example, random module is imported, but this...
Now, please copy the following code and name it as "Contr...
The code as following functionalities
--it executes normal, non-imported code
--imports a system defined module "random", call its attr...
--shows an object-oriented way to import a module into Si...
--using a user-defined module called sample.py which ret...
--use of error parsing
#highlight(c){{
#include "ControllerEvent.h"
#include "Controller.h"
#include "Logger.h"
#include <iostream>
#include <boost/python.hpp>
#include <Python.h>
#include <dlfcn.h>
namespace py = boost::python; // create namespace variabl...
using namespace std;
std::string parse_python_exception(); // functional decla...
template <typename T> string tostr(const T& t) { ostrings...
class MyController : public Controller {
public:
void onInit(InitEvent &evt);
double onAction(ActionEvent&);
void onRecvMsg(RecvMsgEvent &evt);
void onCollision(CollisionEvent &evt);
};
void MyController::onInit(InitEvent &evt) {
SimObj *my = getObj(myname());
dlopen("libpython2.7.so", RTLD_LAZY | RTLD_GLOBAL);
Py_Initialize(); //initialization of the python interp...
}
double MyController::onAction(ActionEvent &evt) {
double x=2.0;
Py_Initialize();
try{
py::object main_module = py::import("__main__");
// load the dictionary object out of the main mod...
py::object main_namespace = main_module.attr("__d...
// run simple code within the main namespace usin...
py::exec("print 'Executing normal, non-imported c...
// function
py::exec("print 'Hello, world'", main_namespace);
// any valid Python will execute
py::exec("print 'Hello, world'[3:5]", main_namesp...
// it is as if you opened a new Python file and w...
// all of the normal functionality is available
py::exec("print '.'.join(['1','2','3'])", main_na...
py::exec("print 'Importing a module that prints r...
// of course, you can also import functionality f...
py::exec("import random", main_namespace);
// boost::python::eval will return the result of ...
// as a boost::python::object
py::object rand = py::eval("random.random()", mai...
// the boost::python::extract function can then c...
// (only as appropriate, of course)
std::cout << py::extract<double>(rand) << std::en...
// or, if you'd prefer, you can extract the func...
// then call them as you wish from C++. this is ...
// of this file. you can't execute code with the...
// extracting the namespace object as we did wit...
// this method ultimately provides a much cleane...
// objects over their lifetimes
py::exec("print 'A more object oriented way to i...
// import the random module
py::object rand_mod = py::import("random");
// extract the random function from the random mo...
py::object rand_func = rand_mod.attr("random");
// call the function and extract the result
// [sidenote: this sort of syntax is what makes ...
py::object rand2 = rand_func();
std::cout << py::extract<double>(rand2) << std::e...
// Here is an example, of reading a list to C++ d...
py::exec("print 'Converting a list to C++ data ty...
py::object randList = py::eval("random.sample(ran...
// call the function and extract the result
// the boost::python::extract function can then r...
// (only as appropriate, of course)
int n = len((randList));
for(unsigned int i=0; i<n; i++){
std::cout << py::extract<double>((randList)[i...
}
// Here is an example, of importing a user define...
// The list is extracted into a C++ Data type.
py::exec("print ' User defined python module that r...
py::object sample_module = py::import("sample");
py::object sample_func = sample_module.attr("...
py::object func_list = sample_func();
int x = len((func_list));
for(unsigned int i=0; i<x; i++){
std::cout << py::extract<double>((func_list)[...
}
}catch(boost::python::error_already_set const &){
// Parse and output the exception
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str <<...
}
return 1.0;
}
void MyController::onRecvMsg(RecvMsgEvent &evt) {
}
void MyController::onCollision(CollisionEvent &evt) {
}
extern "C" Controller * createController() {
return new MyController;
}
std::string parse_python_exception(){
PyObject *type_ptr = NULL, *value_ptr = NULL, *traceb...
// Fetch the exception info from the Python C API
PyErr_Fetch(&type_ptr, &value_ptr, &traceback_ptr);
// Fallback error
std::string ret("Unfetchable Python error");
// If the fetch got a type pointer, parse the type in...
if(type_ptr != NULL){
py::handle<> h_type(type_ptr);
py::str type_pstr(h_type);
// Extract the string from the boost::python object
py::extract<std::string> e_type_pstr(type_pstr);
// If a valid string extraction is available, use...
// otherwise use fallback
if(e_type_pstr.check())
ret = e_type_pstr();
else
ret = "Unknown exception type";
}
// Do the same for the exception value (the stringifi...
if(value_ptr != NULL){
py::handle<> h_val(value_ptr);
py::str a(h_val);
py::extract<std::string> returned(a);
if(returned.check())
ret += ": " + returned();
else
ret += std::string(": Unparseable Python erro...
}
// Parse lines from the traceback using the Python tr...
if(traceback_ptr != NULL){
py::handle<> h_tb(traceback_ptr);
// Load the traceback module and the format_tb fu...
py::object tb(py::import("traceback"));
py::object fmt_tb(tb.attr("format_tb"));
// Call format_tb to get a list of traceback stri...
py::object tb_list(fmt_tb(h_tb));
// Join the traceback strings into a single string
py::object tb_str(py::str("\n").join(tb_list));
// Extract the string, check the extraction, and ...
py::extract<std::string> returned(tb_str);
if(returned.check())
ret += ": " + returned();
else
ret += std::string(": Unparseable Python trac...
}
return ret;
}
}}
Please set the following environment variables to set the...
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/p...
Now, execute "make" it will create a ControllerSample.so ...
make
Please copy the following xml file and name it as "WorldS...
#highlight(xml){{
<?xml version="1.0" encoding="utf8"?>
<world name="myworld1">
<gravity x="0.0" y="-980.7" z="0.0"/>
<instanciate class="seToy_D.xml">
<set-attr-value name="name" value="toy_D"/>
<set-attr-value name="language" value="c++"/>
<set-attr-value name="implementation"
value="./ControllerSample.so"/>
<set-attr-value name="dynamics" value="true"/>
<set-attr-value name="x" value="0.0"/>
<set-attr-value name="y" value="60.0"/>
<set-attr-value name="z" value="0.0"/>
<set-attr-value name="mass" value="1.0"/>
<set-attr-value name="collision" value="true"/>
</instanciate>
</world>
}}
Please copy the following python file and name it as "sam...
#highlight(python){{
def simpleList():
import numpy
a = numpy.ones((2,4))
a.tolist()
return a.tolist()[0]
}}
Please copy the following Makefile file and name it as "M...
#highlight(c){{
#sigverse header
SIG_SRC = $(SIGVERSE_PATH)/include/sigverse
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/raghav/pool...
CC = gcc
CPP = g++
AS = as
LD = g++
AR = ar
RANLIB = ranlib
OBJCOPY = objcopy
# external libraries and headers
# change the next line to point to the location of your b...
EXTERN_DIR = /home/raghav/pool
EXTERN_LIBDIR = $(EXTERN_DIR)/lib
EXTERN_INCDIR = $(EXTERN_DIR)/include
EXTERN_BINDIR = $(EXTERN_DIR)/bin
BOOST_PYTHON_LIB = $(EXTERN_LIBDIR)/libboost_python.a
INCDIRS = .
INCDIRS += $(EXTERN_INCDIR)
# you may also need to change this directory if you want ...
# python version
INCDIRS += /usr/include/python2.7
INCDIRS += /usr/lib/python2.7/dist-packages/numpy/core/in...
INCDIR = $(foreach dir, $(INCDIRS), -I$(dir))
%.o: %.cpp
$(CPP) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
#specifying of object file
OBJS = ControllerSample.so
ControllerSample.so: ControllerSample.cpp
g++ -DCONTROLLER -DNDEBUG -DUSE_ODE -DdDOUBLE -I$(S...
#$^ , $+ The names of all the prerequisites, with spa...
# while $+ retains them and preserves their order
clean:
rm -rf *.so *.o $(HWOBJS) hello_world
}}
Also set the PYTHONPATH
export PYTHONPATH=$PYTHONPATH:/path_to_your_work...
Now, please load the world file into Sigverse and push "S...
./sigverse.sh -w ./WorldSample.xml -p your_port_n...
#highlight(end)
#counter
Page: