Python的C API:调用与按引用传递参数(S)Python函数 [英] Python C API: Call a Python function with argument(s) passed by reference
问题描述
我正在写在C Python模块,我需要把它称之为一个Python函数通过引用传递的参数之一。最终的结果应该是什么Python函数确实的说法被保存到原来的C变量。
I'm writing a python module in C and I need to have it call a Python function with one of the arguments passed by "reference". The end result should be that what the Python function does to the argument gets saved into the original C variable.
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);
要测试,我有Python函数的TC presumeFunc重新presents修改传入的整数= 5。当我打印出*简历在这个code的结束,但是,它保留了它的初始值为-1。我知道我误解的东西有关API是如何工作的。有什么建议?
To test, I had the Python function that tcpResumeFunc represents modify the passed-in integer to = 5. When I print out *resume at the end of this code, however, it retains it's initial -1 value. I know I am misunderstanding something about how the API works. Any suggestions?
推荐答案
我想你误解的东西有关变量的Python中是如何工作的。在Python变量不包含值;它们指的是他们 - 就像在Java中,除了没有原始人(甚至不是 INT
)。赋值给一个变量不会覆盖旧的价值;它只是导致变量来引用新的价值,并停止指的是旧的(当时可能是垃圾收集,如果不出意外是指它)。
I think you're misunderstanding something about how variables work in Python. Variables in Python do not contain values; they refer to them - like in Java, except there are no "primitives" (not even int
). Assignment to a variable doesn't overwrite the old value; it simply causes the variable to refer to the new value and cease referring to the old one (which may then be garbage-collected if nothing else refers to it).
为什么不只是实际回报(和使用)的值(因为Python函数总是返回的东西,无论如何,即使这只是无
的隐含回报)?
Why not just actually return (and use) a value (since Python functions always return something anyway, even if it's just the implicit return of None
)?
编辑:通过一个实例的工作,因为它是一个评论回复太长
Working through an example, because it's too long for a comment reply.
从C,我们称之为PyObject_CallFunction,这双手一的PyObject *到Python函数。在Python中,函数参数(我们称之为垃圾邮件
)现指尖-AT的PyObject。
From C, we call PyObject_CallFunction, which hands a PyObject* over to the Python function. In Python, the function parameter (we'll call it spam
) now refers to the pointed-at PyObject.
当我们写垃圾邮件+ = 6
的功能,那就是一样的垃圾=垃圾邮件+ 6
。字节code间preTER得到的PyObject是重新presents值6,运行一个特殊的字节code的检查由两个对象psented转口货值为$ P $,增加了他们,创建一个新的PyObject(或取一个来自缓存),稀土presents的总和。
When we write spam += 6
in the function, that is the same as spam = spam + 6
. The bytecode interpreter gets the PyObject that represents the value 6, runs a special bytecode that inspects the value represented by the two objects, adds them, and creates a new PyObject (or fetches one from a cache) that represents the sum.
然后垃圾邮件
被反弹给新的对象;但垃圾邮件
可变引用的内存围栏Python的一面,而不是同样的事情的PyObject *篱笆的C面。
Then spam
is rebound to the new object; but the spam
variable-reference is on the Python side of the memory fence, and is not the same thing as the PyObject* on the C side of the fence.
因此, resumeInt
做的不获取指着新建/牵强的PyObject。
Thus, resumeInt
does not get pointed at the newly created/fetched PyObject.
它实际上是行为,因为它会用Python调用Python函数完全相同的方式。试试吧:
It is actually behaving the exact same way as it would calling the Python function from Python. Try it:
def fry(spam):
spam += 1
eggs = 3
fry(eggs)
eggs # still 3!
这是因为重新绑定垃圾邮件
不影响鸡蛋
,这是一个独立的变量。我们不是通过引用传递;我们传递 引用按值。这与Java。
This happens because rebinding spam
does not affect eggs
, which is a separate variable. We are not passing by reference; we are passing a reference by value. Just like in Java.
这篇关于Python的C API:调用与按引用传递参数(S)Python函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!