gpt4 book ai didi

c++ - 如何使用 "="运算符复制 boost python 列表或他的引用

转载 作者:行者123 更新时间:2023-11-28 03:01:27 24 4
gpt4 key购买 nike

获取此代码

#include<boost/python>
namespace bp = boost::python;

bp::list py_points; //initial list
other_class* C; // this class have a bp::list attribute called py_list

// ... some code ....

// in this part C.py_list.ptr() is 0x0

other_class->py_list = py_list; // problem here!!

问题出在运算符“=”

在调试器中的object_core.hpp文件中,这是一个boost python核心文件

inline api::object_base& api::object_base::operator=(api::object_base const& rhs)
{
Py_INCREF(rhs.m_ptr);
Py_DECREF(this->m_ptr); // in this line the program fail
this->m_ptr = rhs.m_ptr;
return *this;
}

运算符“=”的正确使用方法是什么

已编辑

问题是堆栈,如果指针 other_class->py_list 为 null(或 None,因为未调用类构造函数)程序无法调用函数 Py_DECREF(不存在NULL 指针之前的引用)

问题是修复调用构造函数

other_class* C = new othe_class(); // fixed!!

最佳答案

问题不在于赋值运算符,问题在于py_list 的内部PyObject 指针是一个nullptr。在大多数情况下,指针不应为空。从 Python 的角度来看,它至少应该管理对 Python None 对象的引用,因为它是由默认构造的 boost::python::object 完成的。 . boost::python::list 的默认构造函数创建一个新的空列表。因此,问题的根源可能存在于 other_class 的构造函数或 “some code” block 中。


为了详细说明标题中提出的问题,在 Boost.Python 中创建引用或复制列表与在 Python 中相同:

  • 赋值运算符将创建对列表的引用。

    >>> a = ['spam']
    >>> b = a
    >>> b
    ['spam']
    >>> a is b
    True
  • 一 jar slice用于创建浅表拷贝的列表。

    >>> a = ['spam']
    >>> b = a[:]
    >>> b
    ['spam']
    >>> a is b
    False

这是一个完整的示例,在注释中注释了 Python 等效代码。

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

/// @brief Mockup class.
struct other_class
{
boost::python::list py_list;
};

/// @brief Helper function to print object id and its string representation.
std::string to_string(boost::python::object& o)
{
std::stringstream stream;
stream << o.ptr() << " = "
<< boost::python::extract<std::string>(o.attr("__str__")())();
return stream.str();
}

int main()
{
using std::cout;
using std::endl;
namespace python = boost::python;

Py_Initialize();
try
{
python::object object; // object = None
cout << to_string(object) << "\n" // print object
<< " is none check: " << object.is_none() // print object is None
<< endl;

// Create other_class and populate its list.
other_class* c = new other_class(); // py_list = []
cout << "c->py_list: " << to_string(c->py_list) // print py_list
<< endl;
c->py_list.append("spam"); // py_list.append("spam")
cout << "c->py_list: " << to_string(c->py_list) // print py_list
<< endl;

// Have list1 reference c->py_list.
python::list list1; // list1 = []
cout << "list1: " << to_string(list1) << "\n" // print list1
<< "assign py_list to list1" << endl;
list1 = c->py_list; // list1 = py_list
cout << "list1: " << to_string(list1) << endl; // print list1

// Modify list1 and observe effects on pylist.
cout << "modify list1" << endl;
list1.append(42); // list1.append(42)
cout << "c->py_list: " << to_string(c->py_list) // print py_list
<< endl;

// Shallow-copy list1.
cout << "copying list1 into list2" << endl;
python::list list2(
list1.slice(python::_, python::_)); // list2 = list1[:]
list2.append("eggs"); // list2.append("eggs")
cout << "list2: " << to_string(list2) << "\n" // print list2
<< "list1: " << to_string(list1) << endl; // print list1

delete c;
}
catch (python::error_already_set&)
{
PyErr_Print();
}
}

输出:

0x804e1ac = None
is none check: 1
c->py_list: 0xb707024c = []
c->py_list: 0xb707024c = ['spam']
list1: 0xb70da98c = []
assign py_list to list1
list1: 0xb707024c = ['spam']
modify list1
c->py_list: 0xb707024c = ['spam', 42]
copying list1 into list2
list2: 0xb707cb0c = ['spam', 42, 'eggs']
list1: 0xb707024c = ['spam', 42]

输出中需要注意的几点:

  • 默认构造的 boost::python::list 对象管理对空列表的引用。 0x804e1acNone,列表对象的内部 PyObject 指针都没有管理对它的引用。
  • list1 = py_list 赋值导致 list1 管理对由 py_list 管理的相同列表的引用。这在 list1 的输出中显示,最初管理对 0xb70da98c 的引用,但在分配后,它管理对 0xb707024c 的引用。通过 list1py_list 管理同一个列表,可以在另一个句柄中观察到通过一个句柄对列表的更改。
  • 切片构建了一个新列表。因此,list2PyObject 内部点管理与 list1 的指针(0xb707cb0c)不同的引用(0xb707024c).

关于c++ - 如何使用 "="运算符复制 boost python 列表或他的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20736754/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com