16.01.2014 Views

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

368 CHAPTER 17 ■ EXTENDING PYTHON<br />

static PyObject *somename(PyObject *self, PyObject *args) {<br />

PyObject *result;<br />

/* Do something here, including allocating result. */<br />

}<br />

Py_INCREF(result); /* Only if needed! */<br />

return result;<br />

The self argument is only actually used in bound methods; in other functions, it will<br />

simply be a NULL pointer.<br />

Note that the call <strong>to</strong> Py_INCREF may not be needed. If the object is created in the function<br />

(for example, using a utility function such as Py_BuildValue), the function will already own a<br />

reference <strong>to</strong> it, and can simply return it. If, however, you wish <strong>to</strong> return None from your function,<br />

you should use the existing object Py_None. In this case, however, the function does not own a<br />

reference <strong>to</strong> Py_None, and so should call Py_INCREF(Py_None) before returning it.<br />

The args parameter contains all the arguments <strong>to</strong> your function (except, if present, the<br />

self argument). In order <strong>to</strong> extract the objects, you use the function PyArg_ParseTuple (for<br />

positional arguments) and PyArg_ParseTupleAndKeywords (for positional and keyword arguments).<br />

I’ll stick <strong>to</strong> positional arguments here.<br />

The function PyArg_ParseTuple has the signature<br />

int PyArg_ParseTuple(PyObject *args, char *format, ...);<br />

The format string describes what arguments you’re expecting, and then you supply the<br />

addresses of the variables you want populated at the end. The return value is a Boolean value:<br />

If it’s true, everything went well; otherwise, there was an error. If there was an error, the proper<br />

preparations for raising an exception will have been made (you can learn more about that in<br />

the documentation) and all you have <strong>to</strong> do is <strong>to</strong> return NULL <strong>to</strong> set it off. So, if we’re not expecting<br />

any arguments (an empty format string), the following is a useful way of handling arguments:<br />

if (!PyArg_ParseTuple(args, "")) {<br />

return NULL;<br />

}<br />

If the code proceeds beyond this statement, we know we have our arguments (in this case<br />

no arguments). Format strings can look like "s" for a string, "i" for an integer, "o" for a <strong>Python</strong><br />

object (there are many more codes), with possible combinations such as "iis" for two integers<br />

and a string. A full reference of how <strong>to</strong> write format strings can be found in the <strong>Python</strong>/C API<br />

Reference (http://python.org/doc/api/arg-parsing.html).<br />

WHAT ABOUT CLASSES? AND OBJECTS? AND TYPES?<br />

You can create your own built-in types and classes in extension modules <strong>to</strong>o. It’s not <strong>to</strong>o hard, really, but still<br />

a rather involved subject, so I’ll skip it for now. If you mainly need <strong>to</strong> fac<strong>to</strong>r out some bottleneck code in<strong>to</strong> C,<br />

using functions will probably be enough for most of your needs anyway. If you want <strong>to</strong> learn how <strong>to</strong> create<br />

types and classes, the <strong>Python</strong> documentation is a good source of information.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!