I have an class Generic
class Generic:
raw_data = []
objects = dict()
and concrete classes
class A(Generic):
raw_data = module.somethingA
class B(Generic):
raw_data = module.somethingB
I want to populate each raw_data
onto each objects
dict of the class.
To that, I'm running:
for object_type in (A, B):
for data in object_type.raw_data:
new_object = object_type(*data)
object_type.objects[id(new_object)] = new_object
However, this does not work because objects
is shared between A
and B
, and I wanted each subclass of Generic
to have their own objects.
How do I achieve this without having to type objects = dict()
on every subclass?
I'm inclined to say that this is a traditional case where a meta class is required (that adds objects
to each new class); is this the case, or is there a simpler option?
Either use a metaclass or use a class decorator.
A class decorator could simply create the attribute:
def add_objects(cls):
cls.objects = {}
return cls
@add_objects
class A(generic):
raw_data = module.somethingA
This doesn't really add anything however; you just replace one line (objects = {}
) with another (@add_objects
).
You could just add the object in your loop:
for object_type in (A, B):
if 'objects' not in vars(object_type):
object_type.objects = {}
for data in object_type.raw_data:
new_object = object_type(*data)
object_type.objects[id(new_object)] = new_object
or copy it (reading the attribute may retrieve the parent class attribute or a direct attribute, it doesn't matter here):
for object_type in (A, B):
object_type.objects = object_type.objects.copy()
for data in object_type.raw_data:
new_object = object_type(*data)
object_type.objects[id(new_object)] = new_object
or create the dictionary from scratch:
for object_type in (A, B):
object_type.object = {
id(new_object): new_object
for data in object_type.raw_data
for new_object in (object_type(*data),)}
I don't think a metaclass is necessary here. Why not just copy the parent class objects before populating each subclass in your loop?
for object_type in (A, B):
# copy Generic.objects onto object_type.objects here
object_type.objects = Generic.objects.copy()
for data in object_type.raw_data:
new_object = object_type(*data)
object_type.objects[id(new_object)] = new_object
Additionally you can modify to use super
and/or deepcopy
if you want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With