bzm3r
bzm3r

Reputation: 4596

Cython: does the __getattr__ method have to be manually implemented when creating an extension type?

Let's say I am creating a new extension type:

cdef class foo:
    int x

    def __cinit__(self, x):
        self.x = x

Do I manually have to create a __getattr__ special method? It seems that way, because foo.__getattr__('x') gives me an error like so:

ImportError: Building module simple_exttype failed: ["AttributeError: type object 'simple_exttypeexttype.foo' has no attribute '__getattr__'\n"]

Note that I tried out the following within C-space, that is I ran the following *.pyx file:

cdef class foo:
    int x

    def __cinit__(self, x):
        self.x = x

myclass = foo(10)
print "myclass.__getattr__('x'): {}".format(myclass.__getattr__('x'))

If it has to be manually implemented, how should it be implemented, if I don't want to use Python dictionaries?

Upvotes: 2

Views: 1013

Answers (1)

Alex Martelli
Alex Martelli

Reputation: 881785

http://docs.cython.org/src/tutorial/cdef_classes.html is pretty clear about this (at the very end of the page):

  • Attributes are by default only accessible from Cython (typed access)
  • Properties can be declared to expose dynamic attributes to Python-space

So here's a workable approach (assuming you want to expose x as read-only and also fixing a typo in your code) -- call this w.g cyt.pyx:

cdef class foo:
    cdef int _x

    def __cinit__(self, x):
        self._x = x

    property x:
        def __get__(self):
            return self._x

Now, once built and installed:

>>> import cyt
>>> a = cyt.foo(23)
>>> a.x
23
>>> getattr(a, 'x')
23

I'm showing that built-in Python function getattr also works -- there's never any reason to get attributes other than by it or plain a.x syntax.

Upvotes: 3

Related Questions