2

好吧,我只是在学习 Python,并且遇到了一些奇怪的行为。我猜垃圾收集器对此负责,但我不确定。

抱歉,我把问题搞砸了

我想重现一些我在使用没有该库的库时遇到的一些奇怪现象,但我失败了。

所以第二次尝试:

我正在使用 Autodesk Maya 的 python API。它只是围绕现有 C++ API 的 python 包装。

所以这段代码:

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))

产生这个输出:

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

所以两者P,Q都是类型MQuaternion,但Q不保存它应该保存的数据。在这里您可以找到课程的文档MQuaternionconjugateIt是结合到位并通过引用返回。

那么现在出了什么问题呢?


这是一个错误的老问题:D

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

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

conjInPlace() 是就地共轭

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

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 123
None

我猜是因为返回的对象testClass(3,4)没有立即被某些东西引用,所以它被删除了。

那么为什么会这样呢?如何提防这类事情?

4

6 回答 6

6

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

于 2013-06-10T19:28:01.053 回答
2

alterMe不返回任何东西 - 这就是你看到 None 的原因。

于 2013-06-10T19:28:15.917 回答
2

您需要创建alertMe方法来返回调用它的对象:

def alterMe(self):
        self.b = 123
        return self

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

于 2013-06-10T19:31:10.750 回答
2

ConjugateIt 在 C++ 中返回一个引用,因此它不会正确返回 python 对象。试试这个:

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

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

于 2013-06-11T00:24:38.380 回答
1

在您的 C++ 示例中,conjInPlace必须仍然返回复杂值,是吗?在您的 Python 示例中,alterMe不产生None,因此B被分配了 value None,就像您conjInPlace返回了某个值 X 一样,然后c将被分配 X。

于 2013-06-10T19:29:56.063 回答
1

在末尾添加alterMe

return self

这里的问题alterMe是没有明确地返回一个值。如果函数末尾没有指定返回值,PythonNone默认返回。这与垃圾收集无关。

于 2013-06-10T19:29:56.790 回答