Python中的面向对象设计问题:组合与继承
我正在学习面向对象编程(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)