Python中的面向对象设计问题:组合与继承

0 投票
2 回答
1014 浏览
提问于 2025-04-17 13:35

我正在学习面向对象编程(OOP),现在遇到了一些设计上的困惑。我有一些文件,这些文件都有头部信息和数据。大约有25种不同类型的文件。每种文件类型都有:一个名字、一个头部类型、一个数据格式,以及一个数据读取器(也就是我会写的方法,用来读取特定文件类型的数据)。一个特定的“数据读取器”可能会读取多种文件类型的数据。

最终,我需要的是数据集。数据集除了包含上述所有属性外,还要包括从源文件读取的所有数据,以及一些其他信息,比如文件名。

正如我所说,我将有大约25种文件类型,而运行代码时可能会处理几百个数据集。文件类型会非常稳定。虽然未来可能会增加新的文件类型,但现有文件类型的属性几乎不会改变,当然在一次运行中是不会改变的。在数据集中,实际的数据可能会随着处理而变化,但与之相关的文件类型的属性是不会变的。

处理文件的第一步是读取它的头部信息,弄清楚它属于哪种文件类型。接下来,通过调用适当文件类型的数据读取器来构建数据集。

现在,我卡在了如何将文件类型的属性放入数据集的最佳方式上。是说数据集是一个“文件类型”,让数据集继承(或者简单地实例化)文件类型更好,还是说数据集有一个文件类型,让文件类型成为数据集的一个属性更好?我需要在Python中实现这个功能。在回答这个问题时,有没有什么Python特有的考虑?谢谢你的帮助。

2 个回答

1

如果我理解得没错,你有几种不同类型的文件或者不同的文件格式。这些文件里有数据集,而这些数据集的格式并不是特定于某一种类型的。

在这种情况下,我会创建一个类来判断文件的类型和数据的格式。一旦确定了文件类型和数据格式,你就可以创建相应的文件类型和数据格式的对象。

class Detector(object):
    @classmethod
    def detect(cls, filename):
       """Return a file object"""
       pass

    @classmethod
    def infer_filetype(cls, header):
       pass

    @classmethod
    def infer_data_format(cls, contents):
       pass

class File(object):

    def __init__(self, reader)
        pass

    def data(self):
       pass
    ...
    # Other attributes.


class Reader(object)
    """An iterable to read the contents"""
1

如果我理解得没错的话,我会这样做:

class DataReader: #Your base for all readers
    @classmethod
    def read (_, file): pass #magic happens here

class DataReaders:
    def __init__ (self):
        self.__readers = # something like {FileType1: reader1, FileType2: reader1, FileType3: reader3}
    def __getitem__ (self, fileType): return self.__readers [fileType]


class DataSet:
    def __init__ (self, file, readers):
        self.__file = file
        self.readFileType ()
        self.data = readers [self.__fileType].read (file)

    def readFileType (self):
        self.__fileType = #parse the header of the file or whatever

readers = DataReaders ()
ds1 = DataSet (file1, readers)
ds2 = DataSet (file2, readers)

撰写回答