Given the following code, the next step I would like to try to take would be to have the exec call be replaced with the exec_file call, but apparently there is alot I don't understand yet.
[source]#include "stdafx.h"
namespace py = boost::python;
class Object {
public:
Object(int id) :
id(id) {
}
virtual ~Object() {
}
int getId() const {
return id;
}
virtual int f() {
std::cout << "Object" << std::endl;
return 0;
}
private:
int id;
};
struct Derived: Object {
Derived(int i) :
Object(i) {
}
virtual int f(void) {
std::cout << "Derived\n";
return 0;
}
};
struct ObjectWrap: public Object, public py::wrapper<object> {
ObjectWrap(int i) :
Object(i) {
}
int f() {
if (py::override f = this->get_override("f")) {
return f();
}
return Object::f();
}
int default_f() {
return this->Object::f();
}
};
BOOST_PYTHON_MODULE(Core) {
py::class_<object, boost::shared_ptr<object="">, boost::noncopyable>("__Object", "I'm an implementation detail, Pretend I don't exist", py::no_init)
.add_property("id", &Object::getId)
.def("f", &Object::f);
py::class_<objectwrap, boost::shared_ptr<objectwrap="">, boost::noncopyable>("Object", py::init<int>())
.add_property("id", &Object::getId)
.def("f", &Object::f, &ObjectWrap::default_f);
}
int _tmain(int argc, _TCHAR* argv[]) {
Py_Initialize();
try {
initCore();
py::object main_module = py::import("__main__");
py::object main_namespace = main_module.attr("__dict__");
py::object ignored3 = py::exec_file("CustomObject.py", main_namespace,
main_namespace);
py::object ignored = py::exec("import Core\n"
"class CustomObject(Core.Object):\n"
" def __init__(self,id):\n"
" Core.Object.__init__(self,id)\n"
" def f(self):\n"
" print \"CustomObject\"\n"
" return 0\n"
"object = CustomObject(1337)\n", main_namespace, main_namespace);
py::object object = main_namespace["object"];
object.attr("f")();
boost::shared_ptr<object> o = py::extract<boost::shared_ptr<object>>(
object);
o->f();
boost::shared_ptr<object> o2(new Derived(1337));
main_namespace["object"] = o2;
py::object ignored2 = py::exec("object.f()\n", main_namespace,
main_namespace);
} catch (const py::error_already_set&) {
PyErr_Print();
}
Py_Finalize();
system("pause");
return 0;
}[/source]
When I uncomment the line with the exec_file call, and comment out the line with the exec call, I get the following error:
Traceback (most recent call last):
File "CustomObject.py", line 10, in <module>
object = CustomObject(1337)
File "CustomObject.py", line 5, in __init__
Core.Object.__init__self(id)
AttributeError: type object 'Object' has no attribute '_CustomObject__init__self'
I am guessing this is happening because my base class, Object is not able to be imported into the main namespace, being that it is defined on the C++ side? Or not, I really have no clue and am just stabbing in the dark here.
The code, as posted, works just fine, but isn't all that useful to me since it's executing a Python string defined in C++. I could read the .py files into a string, and use the exec call to execute them that way, but the exec_file seems much more elegant. Unfortunately, all the examples end at this point, and leave incorporating reading actual Python scripts as an exercise for the reader.
Can anyone point me in the right direction, and at least verify that my approach is valid?
Edit: There is definitely something wrong with the source tags, putting lang="cpp" in there caused it to seem to choke on the double less than symbol. At least all of the code is there now. If a mod wants to fix it or enlighten me on the subtleties of the new forum software, I'd appreciate it.