Python的C API:调用与按引用传递参数(S)Python函数 [英] Python C API: Call a Python function with argument(s) passed by reference

查看:527
本文介绍了Python的C API:调用与按引用传递参数(S)Python函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆