Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #18757 > unrolled thread

Re: C-API: Pass a tuple to a method of a class

Started byStefan Behnel <stefan_ml@behnel.de>
First post2012-01-10 14:01 +0100
Last post2012-01-10 14:01 +0100
Articles 1 — 1 participant

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: C-API: Pass a tuple to a method of a class Stefan Behnel <stefan_ml@behnel.de> - 2012-01-10 14:01 +0100

#18757 — Re: C-API: Pass a tuple to a method of a class

FromStefan Behnel <stefan_ml@behnel.de>
Date2012-01-10 14:01 +0100
SubjectRe: C-API: Pass a tuple to a method of a class
Message-ID<mailman.4592.1326200506.27778.python-list@python.org>
Hi again,

just as a little teaser, to make it clear that I'm not joking, here's your
code below translated into Cython.

Stefan Behnel, 10.01.2012 13:33:
> pasparis@noos.fr, 10.01.2012 11:57:
>> the code is the following:
> [...]
>> // Class
>> pclass = PyObject_GetAttrString(mymod, "cVector");
>> if (pclass == NULL) {
>> Py_DECREF(pclass);
>> cout << "Can't find class\n";
>> }
>>
>> // Parameters/Values
>> args = Py_BuildValue("(f)", 100.0);
>> if (args == NULL) {
>> Py_DECREF(args);
>> cout << "Can't build argument list for class instance\n";
>> }
>>
>> // Object with parameter/value
>> object = PyEval_CallObject(pclass, args);
>> if (object == NULL) {
>> Py_DECREF(object);
>> cout << "Can't create object instance:\n";
>> }
>>
>> // Decrement the argument counter as we'll be using this again
>> Py_DECREF(args);
>>
>> // Get the object method - note we use the object as the object
>> // from which we access the attribute by name, not the class
>> method = PyObject_GetAttrString(object, "ComputeNorm");
>> if (method == NULL) {
>> Py_DECREF(method);
>> cout << "Can't find method\n";
>> }
>>
>> // Decrement the counter for our object, since we now just need
>> // the method reference
>> Py_DECREF(object);
>>
>> // Build our argument list - an empty tuple because there aren't
>> // any arguments
>>
>> cout << "Prepare the Tuple:\n" ;
>> // WE pass a tuple
>> args = PyTuple_New( 3 );
>> if (args == NULL) {
>> Py_DECREF(args);
>> cout << "Can't build argument list for method call\n";
>> }
>>
>> PyObject *py_argument;
>> // 1st argument
>> py_argument = PyFloat_FromDouble(5.);
>> PyTuple_SetItem(args, 0, py_argument);
>>
>> // 2nd argument
>> py_argument = PyFloat_FromDouble(10.);
>> PyTuple_SetItem(args, 1, py_argument);
>>
>> // 3nd argument
>> py_argument = PyFloat_FromDouble(15.);
>> PyTuple_SetItem(args, 2, py_argument);
>>
>> cout << "Before the Exec:\n" ;
>> // Call our object method with arguments
>> //ret = PyEval_CallObject(method,args);
>> ret = PyObject_CallObject(method,args);
> 
> Note that you are calling the method with three arguments here. It appears
> that what you want is *one* argument instead, which happens to be a tuple.
> So you need to wrap it in another tuple for calling. As I said, Cython will
> do that for you.

And here's the Cython code:

"""
# in module "gluecode.pyx" (or whatever you want to name it)

import mModule8

cdef api float compute_norm(float init_value, float x, float y, float z):
    vec = mModule8.cVector(init_value)
    return vec.ComputeNorm( (x,y,z) )
"""

At least, that's what I read from your C code above. I'm assuming here that
your program is using C or C++, and that you want to embed a CPython
runtime in it and be able to execute Python code through it. The above
"compute_norm()" function is exported (as a C function) by the "gluecode"
module which you can import in your C/C++ code (as you did already).

Note also that the Cython code above is substantially more efficient than
your implementation, because it uses faster type conversions and interned
Python names for looking up the class and its method.

Stefan

[toc] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web