Make subclass has its own class attribute

I have a Generic class

 class Generic: raw_data = [] objects = dict() 

and specific classes

 class A(Generic): raw_data = module.somethingA class B(Generic): raw_data = module.somethingB 

I want to fill every raw_data on every objects dict class. To do this, I run:

 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 split between A and B , and I wanted each Generic subclass to have its own objects.

How to achieve this without typing objects = dict() for each subclass?

I am inclined to say that this is a traditional case where a metaclass is required (which adds objects to each new class); in this case, or is there an easier option?

+5
source share
2 answers

Use a metaclass or use a class decorator.

The class decorator can simply create an attribute:

 def add_objects(cls): cls.objects = {} return cls @add_objects class A(generic): raw_data = module.somethingA 

It really adds nothing; you just replace one line ( objects = {} ) with another ( @add_objects ).

You can simply add an object to 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 can get the attribute of the parent class or direct attribute, it does not 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 a 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),)} 
+2
source

I do not think that a metaclass is needed here. Why not just copy the objects of the parent class 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 

In addition, you can change to use super and / or deepcopy if you wish.

+1
source

Source: https://habr.com/ru/post/1240371/


All Articles