我有一个
std::vector<const T*>从c++函数返回:
getallTs()我把T级课程暴露在:
class_<T,T*> 向量是这样的:
class_<std::vector<const T*> >("TsList")
.def(vector_indexing_suite<std::vector<const T*>,true>())
;NoProxy的论点是什么意思?
我将函数公开如下:
def("getallTs", getallTs,
return_value_policy<return_by_value>{});我观察到一种奇怪的行为。
当我从python打来的时候
tlist = getallTs()我得到一个TsList对象。
len(tlist)很管用。
tlist[<anycorrectindex>].<someattribute> 也很管用。
不过,如果我只是
print(tlist[0])和
print(tlist[100])python打印
object T at <address>这个地址对于tlist中的所有Ts都是相同的。
而且,我不能使用pythonfor循环迭代Tlist。
for t in tlist: 不起作用。
有什么想法吗?我向python公开向量和函数的方式有什么问题?
我理解每个包一个c++ T的python对象,持有一个指向T的原始指针。这些T实例存在于全局表的整个过程中。
c++函数重新运行指向这些实例的指针向量。indexing_suite对这些做了什么?
谢谢,
发布于 2015-09-17 14:45:16
当按索引访问元素时,索引套件默认为元素提供代理,作为为Python用户通常期望的可更改类型提供引用语义的一种方法:
val = c[i]
c[i].m() # Mutates state, equivalent to `val.m()`
assert(val == c[i]) # Have same state.
val.m()
assert(val == c[i]) # Have same state.在上面的示例中,val是一个代理对象,它知道容器元素。当NoProxy是true时,在索引时获得值语义,从而在每次索引访问上产生一个副本。
val = c[i] # val is a copy.
c[i].m() # Modify a copy of c[i].
assert(val == c[i]) # These have the same state because c[i] returns a new copy.
val.m()
assert(val != c[i]) # These do not have the same state.当不使用代理时,只有在对元素的引用(例如在迭代期间)上调用时,元素的突变才会持续:
for val in c:
val.m() # modification observed in c[#]调用print(c[i])时,将创建一个临时代理对象并将其传递给print,代理对象的生存期将在从print()返回时结束。因此,可以重用临时代理对象使用的内存和标识。这可能导致一些元素似乎具有相同的标识:
id0 = id(c[0]) # id of the temporary proxy
id1 = id(c[1]) # id of another temporary proxy
assert(id0 ?? id1) # Non-deterministic if these will be the same.
assert(c[0] is not c[1]) # Guaranteed to not be the same.另一方面,在代理的生存期内,同一元素的其他代理将具有相同的标识,而不同元素的代理将具有不同的标识:
c0 = c[0] # proxy to element 0.
c0_2 = c[0] # another proxy to element 0.
c1 = c[1] # proxy to element 1
assert(c0 is c0_2)
assert(c0 is c[0])
assert(c0 is not c1)在T被T*公开为持有的情况下,如果没有将const T*转换为Python对象,则std::vector<const T*>上的迭代将失败。将类T公开为T*持有,将自动注册为-Python,而非const T*的-Python转换。在Python中迭代集合时,返回对元素的引用,导致无法从const T*构造Python对象。另一方面,当通过索引访问元素时,生成的Python对象要么是代理,要么是副本,可以使用现有的转换器。要解决这一问题,可以考虑:
std::vector<>的元素类型与T的持有类型相同。const T*到-Python转换器https://stackoverflow.com/questions/32567771
复制相似问题