I have defined a generic class Rule in Cython which expects a cdef method ̀initialize. I have created a class which is itself defined as a Rule, but it executes the initialize methods of a list of rules:
%%cython
cdef class Rule:
cdef initialize(self, const int i):
pass
cdef class Print(Rule):
cdef int number
def __init__(self, int number):
self.number = number
cdef initialize(self, const int i):
print(self.number, i)
cdef class ChainRule(Rule):
cdef list rules
cdef int number_of_rules, j
def __init__(self, rules):
self.rules = rules
self.number_of_rules = len(rules)
cdef initialize(self, const int i):
for j in range(self.number_of_rules):
self.rules[j].initialize(i)
def run(Rule rule, const int i):
rule.initialize(i)
The following code works when ̀run` takes Print as input:
rule1 = Print(1)
rule2 = Print(2)
run(rule1, 100)
But the ChainRule class which calls the rules internally does not work:
chain_rule = ChainRule([rule1, rule2])
run(chain_rule, 100)
Error message:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
/tmp/ipykernel_12612/3538048733.py in <module>
4 chain_rule = ChainRule([rule1, rule2])
5
----> 6 run(chain_rule, 100)
_cython_magic_d892e8623ea7126dd1dda2c25ea23c19.pyx in _cython_magic_d892e8623ea7126dd1dda2c25ea23c19.run()
_cython_magic_d892e8623ea7126dd1dda2c25ea23c19.pyx in _cython_magic_d892e8623ea7126dd1dda2c25ea23c19.ChainRule.initialize()
AttributeError: '_cython_magic_d892e8623ea7126dd1dda2c25ea23c19.Pri' object has no attribute 'initialize'
Why does it fail? How can I make it work?
Thank you.
Edit, a working solution:
cdef class ChainRule(Rule):
cdef list rules
cdef int number_of_rules, j
def __init__(self, rules):
self.rules = rules
self.number_of_rules = len(rules)
cdef initialize(self, const int i):
cdef Rule rule
for j in range(self.number_of_rules):
rule = self.rules[j]
rule.initialize(i)