Reputation: 703
I am writing a simplistic ORM that would require me to override the methods inside the child classes. Depending on the context, I am either expecting to access the model through the class methods, or through the instance methods, therefore I can not simply override them. I believe this code describes the question well enough:
class A:
@classmethod
def key_fn(cls, id):
raise NotImplementedError('')
@classmethod
def load_all(cls):
yield from db_fetch_prefix(cls.key_fn('')):
class B(A):
@classmethod
def key_fn(cls, id):
return f'/keys/{id}'
# how do I make sure B.key_fn is called here?
B.load_all()
Upvotes: 6
Views: 13936
Reputation: 3105
Your B.key_fn
would be called indeed. But your load_all
returns a generator, because you let it yield from db_fetch_prefix
. You can check this by running print(B.load_all())
at the end. The output will be:
python .\clsss.py
<generator object A.load_all at 0x0521A330>
I don't know what you want to achieve by using yield from
. But an example that shows overriding of classmethods in subclasses is possible would be:
class A:
@classmethod
def key_fn(cls, id):
raise NotImplementedError('')
@classmethod
def load_all(cls):
return cls.key_fn('foo')
class B(A):
@classmethod
def key_fn(cls, id):
return f'/keys/{id}'
print(B.load_all()) # prints "/keys/foo"
Guessing wildly that you want to apply the key_fn
to each item yielded by your generator db_fetch_prefix
(abbreviated to fetch
below), the code below shows B.key_fn
will be used in the presence of generators as well.
def fetch(callback):
for i in range(5): # fake DB fetch
yield callback(i)
class A:
@classmethod
def key_fn(cls, id):
raise NotImplementedError('')
@classmethod
def load_all(cls):
yield from fetch(cls.key_fn)
class B(A):
@classmethod
def key_fn(cls, id):
return f'/keys/{id}'
print(list(B.load_all())) # prints ['/keys/0', '/keys/1', '/keys/2', '/keys/3', '/keys/4']
Upvotes: 4