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


Groups > comp.lang.python > #18757

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

Path csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.org!de-l.enfer-du-nord.net!feeder2.enfer-du-nord.net!tudelft.nl!txtfeed1.tudelft.nl!multikabel.net!newsfeed20.multikabel.net!amsnews11.chello.com!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail
Return-Path <python-python-list@m.gmane.org>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'args': 0.05; 'c/c++': 0.05; 'cpython': 0.05; '"""': 0.07; 'attribute': 0.07; 'c++,': 0.07; 'python': 0.08; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:80.91.229.12': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'received:lo.gmane.org': 0.09; 'runtime': 0.09; 'subject:method': 0.09; 'tuple': 0.09; 'tuple.': 0.09; 'api': 0.09; 'float': 0.13; 'argument': 0.15; 'method.': 0.15; '"before': 0.16; '"can\'t': 0.16; '(args': 0.16; 'args);': 0.16; 'from:addr:behnel.de': 0.16; 'from:addr:stefan_ml': 0.16; 'from:name:stefan behnel': 0.16; 'function)': 0.16; 'pyobject': 0.16; 'received:mnet-online.de': 0.16; 'subject:API': 0.16; 'arguments': 0.18; 'wrap': 0.18; 'appears': 0.19; "aren't": 0.21; '(or': 0.22; 'header:In-Reply- To:1': 0.22; 'conversions': 0.23; 'least,': 0.23; 'ret': 0.23; 'translated': 0.23; 'object,': 0.24; 'stefan': 0.24; 'code': 0.25; 'module': 0.26; "i'm": 0.26; 'function': 0.27; 'import': 0.27; 'pass': 0.29; 'assuming': 0.29; 'skip:p 30': 0.29; 'class': 0.29; 'null)': 0.30; '(as': 0.31; 'list': 0.32; 'header:User-Agent:1': 0.33; 'header:X-Complaints-To:1': 0.33; 'there': 0.33; 'object': 0.33; 'to:addr:python-list': 0.34; 'it.': 0.34; 'calling': 0.34; 'uses': 0.36; 'instead,': 0.37; 'skip:" 10': 0.37; 'reference': 0.37; 'another': 0.37; 'using': 0.38; '2nd': 0.38; 'received:org': 0.38; 'received:de': 0.39; 'to:addr:python.org': 0.40; 'happens': 0.40; 'more': 0.61; 'type': 0.61; 'your': 0.61; 'efficient': 0.62; 'below': 0.63; 'you.': 0.63; 'our': 0.64; 'here': 0.65; 'here.': 0.66; 'it)': 0.67; '1st': 0.70; 'received:93': 0.78
X-Injected-Via-Gmane http://gmane.org/
To python-list@python.org
From Stefan Behnel <stefan_ml@behnel.de>
Subject Re: C-API: Pass a tuple to a method of a class
Date Tue, 10 Jan 2012 14:01:29 +0100
References <ea-mime-4f0c19a2-3df4-7b628f3f@webmail.numericable.fr> <jehb6d$ijh$1@dough.gmane.org>
Mime-Version 1.0
Content-Type text/plain; charset=UTF-8
Content-Transfer-Encoding 7bit
X-Gmane-NNTP-Posting-Host ppp-93-104-6-76.dynamic.mnet-online.de
User-Agent Mozilla/5.0 (X11; Linux x86_64; rv:9.0) Gecko/20111220 Thunderbird/9.0
In-Reply-To <jehb6d$ijh$1@dough.gmane.org>
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.12
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <http://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <http://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.4592.1326200506.27778.python-list@python.org> (permalink)
Lines 103
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1326200507 news.xs4all.nl 6858 [2001:888:2000:d::a6]:54211
X-Complaints-To abuse@xs4all.nl
Xref x330-a1.tempe.blueboxinc.net comp.lang.python:18757

Show key headers only | View raw


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

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

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

csiph-web