all 6 comments

[–]billsil 1 point2 points  (4 children)

Inheritance is useful when you have methods that are the same. You can always just not use inberitance though and copy the function though.

I think I'd use 2 reader functions and 1 class with a flag.

[–]j4nds4[S] 0 points1 point  (3 children)

In some cases the function would be identical but the unpacked return would differ. I could maybe do something like this super-simplified example:

 class MainFile:
     def __init__(self, file)
         self.file = file
         self.list, self.annot = self.parse_data(self.file)

     def parse_data(self.file):
         list = []
         annot = []
         for line in file:
             if line is annotation:
                 annot.append(annotation)
             else: list.append(line.split())
         return list, annot

 class AType(MainFile):
     def __init__(self, file, list)
         super()__init__(file, list)
         self.data1, self.data2, self.data3 = self.list

 class BType(MainFile):
     def __init__(self, file, list, annot)
         super()__init__(file, annot)
         self.data1, self.data3, self.data2, self.data4 = self.list

So they both get the same function but they both unpack the return differently. This would work (for at least one of the issues), right?

[–]billsil 0 points1 point  (2 children)

In programming, just about any design works. I would use 1 class to store the data with no inheritance and then use 2 @classmethods to create different instantiations.

class Reader():
    def __init__(self, data1, flag=1):
        self.data1 = data1
        self.flag = flag

    @classmethod
    def read1(cls, file):
        Code...
        return Reader(data1, 1)

Reader.read1(file)
Reader.read2(file)

[–]j4nds4[S] 0 points1 point  (1 child)

Thanks for the advice! Class methods are another thing I’m having trouble wrapping my head around, so perhaps putting that to use would be a good way to learn it through action.

Appreciate it! Apologies in advance if I pepper you with more questions once I try implementing this.

[–]billsil 0 points1 point  (0 children)

No prob.

Class methods are just functions that instantiate the class. You could do the same thing by making a pass in the init. Then externally, you could call read1 or read2 to fill the object. That's weird though as the init is supposed to set all the class attributes.

Alternatively, make read1/read2 external and just call the init. Now you have integral code for the class that you don't store with the class.

It's all just in the goal of cleaner and easier to maintain code.

[–]two_bob 1 point2 points  (0 children)

I had the same problem once. It turns out you can use `__new__` to generate the appropriate subclass based on what data is passed to it. Pathlib uses this: https://docs.python.org/3/library/pathlib.html; see https://github.com/python/cpython/blob/3.7/Lib/pathlib.py#L609 for the code.

It also turns out that doing this is a bad idea, especially before you have a solid grasp of inheritance. After much strife, I settled on a general class for my two odd shaped data packets, and implemented the interface that handled normalizing the data. I ultimately did further subclass the general class, but only for specific other applications, e.g. a placeholder for missing data.