首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python C API:使用通过引用传递的参数调用Python函数

Python C API:使用通过引用传递的参数调用Python函数
EN

Stack Overflow用户
提问于 2010-12-03 12:49:06
回答 1查看 2.5K关注 0票数 1

我正在用C编写一个python模块,我需要让它使用"reference“传递的一个参数来调用Python函数。最终结果应该是Python函数对参数所做的操作被保存到原始的C变量中。

代码语言:javascript
复制
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的工作原理有些误解。有什么建议吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 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函数的方式完全相同。试试看:

代码语言:javascript
复制
def fry(spam):
  spam += 1

eggs = 3
fry(eggs)
eggs # still 3!

这是因为重新绑定spam不会影响eggs,它是一个单独的变量。我们不是通过引用传递的;我们是通过值传递给一个引用。就像在Java中一样。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4342560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档