Преобразование логического значения Python в C++ (pybind11)

Я пытаюсь преобразовать логическое значение python в логическое значение С++, чтобы его можно было использовать для сравнения, но мне не удалось его успешно получить.

Вот код, который у меня есть до сих пор (предыдущие испытания закомментированы для справки). Любая помощь будет принята с благодарностью. Пока он печатает «True» и «False», когда должен, но я не могу заставить его правильно оценить в выражении C++ if.

py::object mwparser = py::module::import("mwparserfromhell");
py::object code = mwparser.attr("parse")(py::str(text));
py::object filtered = code.attr("filter_templates")();

for(auto temp : filtered) {
    //auto type = template_figure_type(temp.attr("name"));
    auto type = template_figure_type(py::str(temp.attr("name")));
   // py::print("G ");
    //py::print(type);
 //   auto type = "";
    if(type != ""){
        try {
            //list.append(type);
            //return list;
            //py::print(py::str(type));

            py::object f = temp.attr("has")("link");
            py::print(py::str(f)); //displays "True" and "False" when it should
            //PyObject *t = Py_True;
           // int tr = PyObject_IsTrue(f);

           // if(py::str(f) == py::str("False")) {
            if(py::str(f).is(py::str("True"))) {
            //if(temp.attr("has")("link")) {
            //if(py::str(f) == py::str("True")){
           // if(0){
                temp.attr("remove")("link");
                bContent_changed = true;
                list.append(temp);
            }
            else {
                py::print("NO");
            }
        } catch (std::domain_error) {
            throw std::domain_error("");
        }
    }

РЕДАКТИРОВАТЬ:

if(f == Py_True){

кажется, работает, но устарел. Когда я пытаюсь использовать предложенный «f.is (Py_True)», он выдает ошибку error: reference to type 'const pybind11::detail::object_api<pybind11::handle>' could not bind to an rvalue of type 'PyObject *' (aka '_object *') if(f.is(Py_True)){ ^~~~~~~


person Markyroson    schedule 18.04.2018    source источник


Ответы (2)


Похоже, что это можно решить с помощью следующего изменения в приведенном выше фрагменте кода.

f.is(Py_True)

должно быть

if(py::str(f).is(py::str(Py_True)))

Надеюсь, это поможет другим, у кого может быть такой же вопрос. Важно отметить, что, несмотря на то, что сравнение '==' (f == Py_True) все еще работает (на данный момент), оно устарело.

Для любопытных (работающий) обновленный код выглядит следующим образом:

py::object mwparser = py::module::import("mwparserfromhell");
py::object code = mwparser.attr("parse")(py::str(text));
py::object filtered = code.attr("filter_templates")();

for(auto temp : filtered) {
    auto type = template_figure_type(py::str(temp.attr("name")));
    if(type != ""){
        try {

            py::object f = temp.attr("has")("link");
            py::print(py::str(f)); //displays "True" and "False" when it should
              if(py::str(f).is(py::str(Py_True))){
                temp.attr("remove")("link");
                bContent_changed = true;
                list.append(temp);
            }
            else {
                py::print("NO");
            }
        } catch (std::domain_error) {
            throw std::domain_error("");
        }
}
person Markyroson    schedule 18.04.2018

Проверьте эту функцию

int PyBool_Check(PyObject *o) Возвращает true, если o имеет тип PyBool_Type.

person Zihao Ding    schedule 15.05.2020