1

I am trying to improve this code which uses list type :

# CLASS ORDERC #
################
cdef class OrderC:
    cdef int _side
    cdef float _px
    cdef int _vo

    def __cinit__(self, int side, float px, int vo):
        # ....

    cdef setData(self, double[:] dates):
        # ....

# CLASS LISTORDERC #
####################
cdef class ListOrderC:
    cdef int _B
    cdef list _LO_Bid

    cdef double[:] _dates

    def __init__(self, num.ndarray[num.double_t, ndim=1] dates):
        self._B = 0
        self._LO_Bid = []
        self._dates = dates

    cpdef addOrder(self, OrderC oo):
       self._B += 1
       self._LO_Bid.append(oo)
       self._LO_Bid[-1].setData(self._dates)

The problem arrives when i call addOrder from python :

 AttributeError: 'OrderC.OrderC' object has no attribute 'setData'

I guess it's because OrderC is recognized as python object, so I have to define setData with cpdef. But I want OrderC to be recognized as the cdef class to imporve the performance.

Could you please help me ?

Thanks

MiKL
  • 73
  • 10
  • In the code you posted, the methods are not indented correctly. You just define a free function `setData()` independently from `OrderC`. You need to format the classes like you normal Python classes. – sth Sep 10 '14 at 12:53
  • Yes, it is a mistake on the post only. In my code, the indentation is correct. I made corrections to this post. – MiKL Sep 10 '14 at 13:05
  • Related 1) [arrays of cdef class](https://stackoverflow.com/questions/33851333/cython-how-do-you-create-an-array-of-cdef-class) 2) About `AttributeErrors` when looking up classes in lists: https://stackoverflow.com/questions/66067323/cant-use-attributes-of-a-class-from-a-list-of-that-classes-in-cython https://stackoverflow.com/questions/55230665/cython-class-attributeerror – DavidW Mar 26 '21 at 09:20

1 Answers1

1

The problem is that list only holds things of type object, so when you access you get back an object.

You probably want to use a C++ vector instead.

Veedrac
  • 58,273
  • 15
  • 112
  • 169
  • I was wondering whether `cdef OrderC orderc = self._LO_Bid[-1]` and `orderc.setData(...)` would work ? – sebdelsol Sep 11 '14 at 01:13
  • Probably, but it's also likely to be slower because it has to check the types match and then unpack it. You can do unchecked casts, but even then a `vector` will be faster. – Veedrac Sep 11 '14 at 02:04
  • Sebdel's solution works but performs a bit slower than my current solution. Cython doesn't let me compile a vector of OrderC pointer cdef vector but not cdef public vector. So I think that it will slow down my code since I will have to cast it as python object every time I wnat to acces it from python. – MiKL Sep 11 '14 at 08:10
  • If you want fast access from Python as well, you could make every `OrderC` store `object` pointers to itself and return those on access from Python. No guarantees it'll work, but I don't see why it wouldn't. – Veedrac Sep 11 '14 at 14:57