0

I am currently learning how to write Python (v3.5) extension modules using the Python C API. Some operations, like fast numerical work, are best done in C, while other operations, like string manipulation, are far easier to implement in Python. Is there an agreed-upon way to use both Python and C code to define a new type?

For example, I've written a Matrix type in C that supports basic storage and arithmetic operations. I want to define the Matrix.__str__ using Python, where string manipulations are much easier and I don't need to worry about cstrings.

I attempted to define the __str__ method when the module loads in __init__.py as follows:

from mymodule._mymodule import Matrix;

def as_str(self):
    print("This is a matrix!");

Matrix.__str__ = as_str;

When I run this code, I get a TypeError: can't set attributes of built-in/extension type 'matey.Matrix'. Is there an acceptable way to do this? If the solution is to subclass Matrix instead, what is the best way to keep my C base classes / Python subclasses organized within a module?

Benjamin Bray
  • 416
  • 4
  • 14

2 Answers2

0

Personally, I wouldn't try and do object-oriented stuff in C. I'd stick to writing a module which exposes some (stateless) functions.

If I wanted the Python interface to be object oriented, I'd write a class in Python which imports that (C extension) module and consumes functions from it. Maintaining of any state would all be done in Python.

eddiewould
  • 1,555
  • 16
  • 36
  • Structs will probably come in useful for complex data (e.g. matrices). Look into ctypes.Structure – eddiewould Oct 29 '16 at 04:25
  • Good idea. However, I'm trying to emulate how `numpy` arrays work (just to learn, I know better than to roll my own linear algebra routines in production). I'd like to store the matrix data in C since copying back and forth would be too slow. – Benjamin Bray Oct 29 '16 at 04:28
  • Yeah - hence my suggestion to use C structs for representing matrix data. You can access those C structs in Python without any "copying back an forth". – eddiewould Oct 29 '16 at 04:30
  • Have a look at this: http://www.ifnamemain.com/posts/2013/Dec/10/c_structs_python/ – eddiewould Oct 29 '16 at 04:31
  • Thanks, I'll look into it! (I didn't see your comment before posting mine, you're too fast :) ) – Benjamin Bray Oct 29 '16 at 04:33
0

You could instead define a _Matrix type which you then extend with a traditional OOP approach

from mymodule._mymodule import _Matrix;

class Matrix(_Matrix):
    def __str__(self):
        return "This is a matrix!"
tynn
  • 38,113
  • 8
  • 108
  • 143