我正在用C编写一个python模块,我需要让它使用"reference“传递的一个参数来调用Python函数。最终结果应该是Python函数对参数所做的操作被保存到原始的C变量中。
int *resume; // this int is actually passed in to this body of code
PyObject *resumeInt; // which was originally a C callback func for libnids, but
PyObject *ret; // I removed/rewrote most of this code for clarity
resumeInt = Py_BuildValue("i",-1);
ret = PyObject_CallFunction(tcpResumeFunc, "(O)", resumeInt);
*resume = PyInt_AsLong(resumeInt);
Py_DECREF(ret);
Py_DECREF(resumeInt);为了进行测试,我让tcpResumeFunc表示的Python函数将传入的整数修改为= 5。然而,当我在这段代码的末尾输出*resume时,它保留了它的初始值-1。我知道我对API的工作原理有些误解。有什么建议吗?
发布于 2010-12-03 12:56:33
我认为你误解了Python中变量的工作原理。Python中的变量不包含值;它们引用这些值-就像在Java语言中一样,只是没有“原语”(甚至不是int)。对变量的赋值不会覆盖旧值;它只会导致变量引用新值并停止引用旧值(如果没有其他引用,则可能会对旧值进行垃圾回收)。
为什么不直接返回(并使用)一个值(因为Python函数总是返回一些东西,即使它只是None的隐式返回)?
编辑:处理一个示例,因为回复评论太长了。
在C中,我们调用PyObject_CallFunction,它将一个PyObject*传递给Python函数。在Python语言中,函数参数(我们称之为spam)现在引用指向的PyObject。
当我们在函数中编写spam += 6时,这与spam = spam + 6相同。字节码解释器获取表示值6的PyObject,运行一个特殊的字节码来检查这两个对象表示的值,将它们相加,然后创建一个表示和的新PyObject (或从缓存中获取一个)。
然后spam被重新绑定到新对象;但是spam变量引用位于内存围栏的Python端,并且与围栏C端的PyObject*不是一回事。
因此,resumeInt不会将指向新创建/获取的PyObject。
实际上,它的行为与从Python调用Python函数的方式完全相同。试试看:
def fry(spam):
spam += 1
eggs = 3
fry(eggs)
eggs # still 3!这是因为重新绑定spam不会影响eggs,它是一个单独的变量。我们不是通过引用传递的;我们是通过值传递给一个引用。就像在Java中一样。
https://stackoverflow.com/questions/4342560
复制相似问题