Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
嵌入式环境中的Python调试shell:exec还是eval? 我在C++中使用Posi::Python构建了一个嵌入式Python应用程序。嵌入式环境将自身的一部分导出为模块,换句话说,在环境中运行的python代码不会在标准python环境中运行,因为无法导入嵌入式模块_C++_Python 3.x_Boost Python - Fatal编程技术网

嵌入式环境中的Python调试shell:exec还是eval? 我在C++中使用Posi::Python构建了一个嵌入式Python应用程序。嵌入式环境将自身的一部分导出为模块,换句话说,在环境中运行的python代码不会在标准python环境中运行,因为无法导入嵌入式模块

嵌入式环境中的Python调试shell:exec还是eval? 我在C++中使用Posi::Python构建了一个嵌入式Python应用程序。嵌入式环境将自身的一部分导出为模块,换句话说,在环境中运行的python代码不会在标准python环境中运行,因为无法导入嵌入式模块,c++,python-3.x,boost-python,C++,Python 3.x,Boost Python,真正有助于调试的特性之一是调试shell,在这里我可以突破并手动输入标准python表达式来检查/修改当前状态。我的问题是,我不/无法提前知道这是评估(如“2+2”)还是执行(如“a=2+2”)。如果我exec(“2+2”),我不会得到结果,如果我eval(“a=2+2”),我会得到一个语法错误。(来自C语言背景的我不太明白为什么会有这种区别)。首先尝试eval,如果失败则尝试exec,这似乎是一个非常可疑的解决方案,不仅仅是因为副作用 我可以看到Boo::Python只是复制Python的EV

真正有助于调试的特性之一是调试shell,在这里我可以突破并手动输入标准python表达式来检查/修改当前状态。我的问题是,我不/无法提前知道这是评估(如“2+2”)还是执行(如“a=2+2”)。如果我exec(“2+2”),我不会得到结果,如果我eval(“a=2+2”),我会得到一个语法错误。(来自C语言背景的我不太明白为什么会有这种区别)。首先尝试eval,如果失败则尝试exec,这似乎是一个非常可疑的解决方案,不仅仅是因为副作用

我可以看到Boo::Python只是复制Python的EVA/ExEC函数,所以这个问题更多的是在Python级别,但是我希望得到的答案是如何在C++(理想的Boost)级别上完成它。是否有一些异常复杂的正则表达式可以用来区分可执行代码和可评估代码?现在,我只是使用一个丑陋的解决方案,让用户在表达式上加一个前缀来决定

这是一个带有TODO的MCVE,我需要在eval和exec之间进行选择(obv.需要python dev和boost_python libs)

//g++$(python3配置--cflags)so.cpp-fPIC-lboost\u python3$(python3配置--ldflags)
#包括
#包括
#包括
名称空间py=boost::python;
std::string pyobject_to_string(pyobject*obj)
{
PyObject*repr=PyObject_Str(obj);
PyObject*str=PyUnicode_AsEncodedString(repr,“utf-8”,“~E~”;
const char*bytes=PyBytes作为字符串(str);
Py_XDECREF(repr);
Py_XDECREF(str);
返回std::字符串(字节);
}
int main(int argc,常量字符**argv)
{
//初始化python环境
Py_初始化();
如果(argc<2)
{
返回1;
}
尝试
{
//TODO根据需要调用的argv[1]决定:
py::object res=py::eval(argv[1]);

std::cout导入和使用可能更容易。是的,代码模块将至少部分解决我的问题。
// g++ $(python3-config --cflags) so.cpp -fPIC -lboost_python3 $(python3-config --ldflags)

#include <boost/python.hpp>
#include <string>
#include <iostream>

namespace py = boost::python;

std::string pyobject_to_string(PyObject* obj)
{
  PyObject* repr = PyObject_Str(obj);
  PyObject* str = PyUnicode_AsEncodedString(repr, "utf-8", "~E~");
  const char *bytes = PyBytes_AS_STRING(str);

  Py_XDECREF(repr);
  Py_XDECREF(str);
  return std::string(bytes);
}


int main(int argc, const char** argv)
{
  // Init python env
  Py_Initialize();

  if (argc < 2)
  {
    return 1;
  }
  try
  {
    // TODO decide, based on argv[1], which needs to be called, this:
    py::object res = py::eval(argv[1]);
    std::cout << pyobject_to_string(res.ptr()) << std::endl;
    // or this:
    py::exec(argv[1]);
    // or something else entirely...?
  }
  catch(py::error_already_set&)
  {
    if (PyErr_Occurred())
    {
      PyObject *type, *value, *traceback;
      PyErr_Fetch(&type, &value, &traceback);

      std::string message = pyobject_to_string(type) + ":" + pyobject_to_string(value);
      //PyErr_Restore(type, value, traceback);
      std::cerr << message << std::endl;
    }
    else
    {
      std::cerr << "unknown error" << std::endl;
      return 1;
    }
  }
}
$ ./a.out 2+2
4
$ ./a.out a=2+2
<class 'SyntaxError'>:('invalid syntax', ('<string>', 1, 2, 'a=2+2'))