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

3
  • 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. Commented Sep 10, 2014 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. Commented Sep 10, 2014 at 13:05
  • Related 1) arrays of cdef class 2) About AttributeErrors when looking up classes in lists: stackoverflow.com/questions/66067323/… stackoverflow.com/questions/55230665/… Commented Mar 26, 2021 at 9:20

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I was wondering whether cdef OrderC orderc = self._LO_Bid[-1] and orderc.setData(...) would work ?
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.
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<OrderC*> but not cdef public vector<OrderC*>. 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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.