As @DavidW has pointed out, the problem of cdef-classes is that they have no __dict__. You can add __dict__ to the class-definition, if really desired:
%%cython cdef class A: cdef dict __dict__ # now the usual attribute look-up is possible cdef readonly int answer def __init__(self): self.answer = 42 #cdef attribute self.question = "unknown" #pure python attribute, possible
And now:
a=A() print(a.answer) # 42 print(a.question) # 'unknown' a.question = 'Why?' print(a.question) # 'Why?' setattr(a, 'new_attr', None) print(a.new_attr) # None
Note: setattr(a,'new_attr', None) would be not possible if cdef class A were defined without __dict__, but with cdef public object question instead.
Obviously there are additional cost using __dict__, so probably one would use the predefined attributes whenever the performance matters. One of advantages of cdef-classes is smaller memory-footprint (for example because there is no __dict__-slot). So adding __dict__-slot would negate at least some of advantages - one should ask, whether another design would be a better option - but there are obviously scenarios, where adding __dict__-slot makes sense.
Another way would be to create a subclass of the cdef class and use it rather than the base-class.
Once the __dict__ slot is defined, instances of class A have the__dict__-attribute (which is not the case for usual cdef-classes). However, __dict__ doesn't contain cdef-attributes, e.g. answer from the example above (no matter whether they are public or not) - only the normal pure python attributes (e.g. question and new_attr in the example above).
Here for the example above:
# no answer-attribute in __dict__: a.__dict__ # {'new_attr': None, 'question': 'Why?'}
NB: here is the part in the Cython-documentation about dynamic attributes.