Can you update an unchanging class dictionary in a subclass? (Python)

Viewed 18

I want to be able to do this:

class base:
    Dict = {'attribute_name': (0,4)}

class sub(base):
    Dict['attribute_name'] = (5,10)

I know I can do this by just adding a class method that's called in the init method, but that seems like a bad practice as it repeats a redundant function call for every instance.

Dict in this case is a dictionary containing the names of attributes and the physical location of their values in a bin file. so I wanted to make a new subclass for each type of file. Each type of file contains the same information just in different locations, but may have a different method of reading and writing. Dict contains 50+ items, so it seems redundant to copy and paste the definition of the entire dictionary into every child class to change 2 or 3 values.

Do I just need to refactor the whole thing?

1 Answers

For more context, here's a simplified version of the code.

class base:
    Dict = {'attribute_name': (0,4)}

    def __init__(self,bytestring):
        self.bytearray = bytearray(bytestring)

    def read(self):
        # for each attribute, call its associated set function on its allocated bytes
        for attribute_name, (start,end) in self.Dict.items():
            setattr(self, attribute_name, getattr(self, 'set_'+attribute_name)(self.bytearray[start:end]))

    def write(self):
        # for each attribute, call its associated get function on its allocated bytes
        for attribute_name, (start,end) in self.Dict.items():
            self.bytearray[start:end] = getattr(self, 'get_'+attribute_name)(self.bytearray[start:end])

    def set_attribute_name(self,byte):
        return [int.from_bytes(byte[0:3]),int.from_bytes(byte[3:4],'little')]

    def get_attribute_name(self,byte):
        return int.to_bytes(self.attribute_name[0],3,'little') + int.to_bytes(self.attribute_name[1],1,'little')]

class sub(base):
    Dict['attribute_name'] = (5,10)

    def set_attribute_name(self,byte):
        return [int.from_bytes(byte[0:3]),int.from_bytes(byte[3:5],'little')]

    def get_attribute_name(self,byte):
        return int.to_bytes(self.attribute_name[0],3,'little') + int.to_bytes(self.attribute_name[1],2,'little')]

This allows me to easily modify how existing data is extracted, but also makes grabbing additional data as easy as adding another value to a dictionary and writing a method to handle its extraction. It also makes copying data between file formats really easy because the attributes all have the same names, so they don't need to know how the other format stores its data.

Related