关于垃圾收集:python正在窃取我的对象

python is stealing objects from me

我只是在学习Python,我正在经历一些奇怪的行为。我想是垃圾收集者造成的,但我不确定。

对不起,伙计们,我把问题搞砸了

我想重现我在使用没有那个图书馆的图书馆时所得到的一些奇怪之处,但我不幸地失败了。

所以第二次尝试:

我使用的是欧特克玛雅的python api。它只是Python环绕现有C++ API的包装。

所以这个代码:

1
2
3
4
5
6
7
import maya.OpenMaya as om

Q = om.MQuaternion(1,2,3,4).conjugateIt()
P = om.MQuaternion(6,6,6,6)
print(Q[0],Q[1],Q[2],Q[3])
print(type(Q))
print(type(P))

生成此输出:

1
2
3
(6.0, 6.0, 6.0, 6.0)
<class 'maya.OpenMaya.MQuaternion'>
<class 'maya.OpenMaya.MQuaternion'>

因此,两个P,Q都是MQuaternion类型,但Q不保存它应该保存的数据。您可以在这里找到MQuaternion类的文档。conjugateIt是位共轭,参照返回。

那么现在怎么了?

这里有一个老问题,它是错误的:d

在C++中,我习惯于这样做。

1
complex<float> c = complex<float>(1,2).conjInPlace()

conxinplace()已就位

但是如果我在python中做类似的事情,我就会遇到麻烦。

1
2
3
4
5
6
7
8
9
10
11
12
13
class testClass:
        def __init__(self,_a,_b):
            self.a = _a
            self.b = _b
        def alterMe(self):
            self.b = 123

A = testClass(1,2)
A.alterMe()
print(A.a,A.b)
B = testClass(0,0)
B = testClass(3,4).alterMe()
print(B)

给我输出:

1
2
1 123
None

我想是因为testClass(3,4)返回的对象不会立即被某个对象引用,所以会被删除。

为什么会这样?如何注意这类事情?


A确实被alterMe方法改变了。但是,B被设置为该方法的返回值,即None对象,而不是另一个testClass对象。


ConjugateIt在C++中返回一个引用,所以它不会正确地返回Python对象。试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
Q = om.MQuaternion(1.0,2.0,3.0,4.0)
print Q.x, Q.y, Q.z, Q.w
Q.conjugateIt()
print Q.x, Q.y, Q.z, Q.w
print"----"
P = om.MQuaternion(6,6,6,6)
print P.x, P.y, P.z, P.w

# 1.0 2.0 3.0 4.0
# -1.0 -2.0 -3.0 4.0
# ----
# 6.0 6.0 6.0 6.0

更新了第一行以反映汤姆的观察结果


您需要使alertMe方法返回从其调用的对象:

1
2
3
def alterMe(self):
        self.b = 123
        return self

也就是说,testClass(3, 4)返回一个对象,但当调用alertme时,该对象不返回任何对象。通过上述修复,它将再次返回对象。


alterMe什么也不返回——这就是为什么你看不到的原因。


alterMe末尾加上:

1
return self

这里的问题是alterMe没有显式返回值。如果函数末尾没有指定返回值,则python默认返回None。这与垃圾收集无关。


在C++示例中,EDCOX1 OR 6必须仍然返回复数值,是吗?在python示例中,alterMe不生成None,因此B被赋值为None,就像conjInPlace返回了某个值x,那么c将被赋值为x。