SWIG interfacing C library to Python (Creating 'iterable' Python data type from C 'sequence' struct)

后端 未结 4 1265
北海茫月
北海茫月 2020-12-01 15:17

I have written a Python extension for a C library. I have a data structure that looks like this:

typedef struct _mystruct{
   double * clientdata;
   size_t          


        
4条回答
  •  有刺的猬
    2020-12-01 16:02

    You say you have yet to implement Python exception throwing - that's the problem. From PEP 234:

    A new exception is defined, StopIteration, which can be used to signal the end of an iteration.

    You must set this exception at the end of your iteration. Since your code doesn't do this, you're running into the situation you've described:

    1. The interpreter loops through your list's custom iternext function
    2. Your function gets to the end of the array, and rather than correctly setting the StopIteration exception, simply returns your 'magic number'.
    3. The interpreter, seeing no good reason to stop iterating, simply continues to print the value returned by iternext... your magic number. To the interpreter, it's just yet another list member.

    Fortunately, this is a pretty simple fix, though may not seem as straightforward, because C has no exception facility. The Python C API simply uses a global error indicator that you set when an exception situation is raised, and then the API standards dictate you return NULL all the way up the stack to the interpreter, which then looks at the output of PyErr_Occurred() to see if an error is set, and if it is, prints the relevant exception and traceback.

    So in your function, when you reach the end of the array, you just need this:

    PyErr_SetString(PyExc_StopIteration,"End of list");
    return NULL;
    

    Here's another great answer for further reading on this issue: How to create a generator/iterator with the Python C API?

提交回复
热议问题