如何打印boost.python中的自定义python类型
我正在尝试使用boost.python库,以便从Python Skyfield API中获取数据,但是我很难打印出数据。该程序运行,但我会收到此错误:“ python中的错误:< class'typeError'>:'nontype'对象无法callable”。
正确的输出应该显示这样的东西: 10h 47m 56.24s +09DEG 03'23.1” 2.33251 AU
我正在使用本网站上的第一个代码示例作为参考: https://rhodesmill.org.org/skyfield/skyfield/skyfield/
如果您对如何正确输出数据有任何想法,请告诉我!
到目前为止,这是我的代码:
#include <iostream>
#include <boost/python.hpp>
#include <Python.h>
namespace py = boost::python;
std::string parse_python_exception();
int main()
{
Py_Initialize(); //Initializes the Python interpreter
//Imports the __main__ module and extracts the namespace
//This creates a blank 'canvas' upon which we can call Python code
py::object main_module = py::import("__main__");
//Loads the dictionary object from the main module
py::object main_namespace = main_module.attr("__dict__");
try
{
//Imports
py::exec("from skyfield.api import load");
py::object skyfield_mod = py::import("skyfield.api");
py::object skyfield_load = skyfield_mod.attr("load");
py::object skyfield_load_timescale = skyfield_load.attr("timescale");
py::exec("print('This program computes the current position of Mars in the sky')", main_namespace);
py::object ts = skyfield_load_timescale();
py::object ts_now = ts.attr("now");
py::object t = ts_now();
py::object planets = skyfield_load("de421.bsp");
py::object earth = planets["earth"];
py::object mars = planets["mars"];
py::object earth_at = earth.attr("at");
py::object earth_at_observe = earth_at(t).attr("observe");
py::object m_earth_at_observe = earth_at_observe(mars);
py::object astrometric = m_earth_at_observe;
py::object ra, dec, distance = astrometric.attr("radec");
py::object m_ra = ra();
py::object m_dec = dec();
py::object m_distance = distance();
py::exec("print(m_ra)", main_namespace);
}
catch (boost::python::error_already_set const&)
{
std::string perror_str = parse_python_exception();
std::cout << "Error in Python: " << perror_str << std::endl;
}
}
// Parses the value of the active python exception
// NOTE SHOULD NOT BE CALLED IF NO EXCEPTION
std::string parse_python_exception() {
PyObject* type_ptr = NULL, * value_ptr = NULL, * traceback_ptr = NULL;
// 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 into the exception string
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 it
// 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 stringification of the exception)
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 error: ");
}
// Parse lines from the traceback using the Python traceback module
if (traceback_ptr != NULL) {
py::handle<> h_tb(traceback_ptr);
// Load the traceback module and the format_tb function
py::object tb(py::import("traceback"));
py::object fmt_tb(tb.attr("format_tb"));
// Call format_tb to get a list of traceback strings
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 fallback in necessary
py::extract<std::string> returned(tb_str);
if (returned.check())
ret += ": " + returned();
else
ret += std::string(": Unparseable Python traceback");
}
return ret;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论