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) |
给我输出:
我想是因为testClass(3,4)返回的对象不会立即被某个对象引用,所以会被删除。
为什么会这样?如何注意这类事情?
- 型因为你没有从你的alertme函数中返回任何内容
- 型如果您希望示例代码正常工作,那么应该能够将return self添加到alterMe()函数的底部。
- 型你得到的答案是正确的。当然,你可以在alterMe的末尾使用return self,我已经完成了类似的代码,但是修改和返回自己通常被认为是"非Python式的"。
- 型天哪,如果垃圾收集器是那样的攻击性,那么Python将是一种更糟糕的代码语言。
- 型哈哈哈:我把所有的事情都搞砸了:D抱歉,小伙子们问了这么一个愚蠢的问题:D
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 |
更新了第一行以反映汤姆的观察结果
- fwiw我不知道为什么Swig包装器会给出一个bum指针作为共轭方法的返回。叹息
- 为什么ConjugateIt是voidIT文档说它是MQuaternion &?
- 我的错-它实际上返回一个引用…虽然在python中不需要它。共轭它在适当的地方修改了q,你已经有了q,所以你可以像上面那样处理它。openmaya python docs download.autodesk.com/us/maya/2010help/&hellip;意味着引用在python中都被视为指针-而且函数似乎返回了一个无意义的"指针"(如果不调用p行,则会看到q中的值是垃圾)
- fwiw,你可以用.共轭代替.共轭得到一个新的四元数。
- 好吧,但我还是不明白为什么它返回非散度指针?!如果我只是简单地回答Q = om.MQuaternion(1,2,3,4).conjugateIt()print(Q[0],Q[1],Q[2],Q[3]),我几乎得到了正确的答案(0.0, -2.0, -3.0, 4.0),所以它指向了记忆的正确部分。但是内存不是为Q保留的,并且通过声明P它会被重写。是的,我最终使用了.conjugate,但我认为这是浪费,我可以用ConjugateIt做得更好。
- 你可能想看看这里的讨论:StaskOfFult.COM/Quass/534 375 /PosialValuePython——这就是为什么它很难将C++习语翻译成Python的原因。在我的系统中,共轭的结果是垃圾(q保留正确的值,但结果值是无意义的)。我认为这里的行为与他们在文档中标题"修改参数值而不是使用赋值"下提到的行为相同。
- UFF这对我来说是一个错误的C++程序员。我在读布莱尔·康拉德的回答,安萨尔,带列表的例子太令人困惑了。在C++中,您可以在初始化过程中设置引用,但它不会在Python中与我接通。
您需要使alertMe方法返回从其调用的对象:
1 2 3
| def alterMe(self):
self.b = 123
return self |
也就是说,testClass(3, 4)返回一个对象,但当调用alertme时,该对象不返回任何对象。通过上述修复,它将再次返回对象。
alterMe什么也不返回——这就是为什么你看不到的原因。
在alterMe末尾加上:
这里的问题是alterMe没有显式返回值。如果函数末尾没有指定返回值,则python默认返回None。这与垃圾收集无关。
- 当然可以吗?
- @我想知道的是…手术期望是什么?self还是self.b?
- @Ó;scarl&243;pez给出了从complex对象返回的complex类型,那么我猜它会做一个return *this;,在python中是return self。
在C++示例中,EDCOX1 OR 6必须仍然返回复数值,是吗?在python示例中,alterMe不生成None,因此B被赋值为None,就像conjInPlace返回了某个值x,那么c将被赋值为x。