处理任意数据:继承和重写基本方法还是提供回调?

时间:2018-12-11 14:56:38

标签: python python-3.x inheritance architecture

我正在编写一个Python类,我们称之为CSVProcessor。其目的如下:

  1. 从CSV文件中提取数据
  2. 以任意方式处理数据
  3. 使用新处理的数据更新数据库

现在看来,对于一堂课来说这太过分了,但是步骤1和3已经依赖高级组件,因此我只需要关注步骤2。
我还建立了以下内容:

  • 在步骤1中提取的数据将存储在列表中
  • 该列表中的每个元素都需要分别进行独立处理,并在步骤2之前彼此独立处理
  • 已处理的数据需要作为列表从步骤2中出来,以便继续执行步骤3

这不是一个难题,Python非常灵活,实际上,我已经找到了两种解决方案,但是我想知道每种解决方案的副作用(如果有)。基本上,应该优先于其他,以及为什么。

解决方案1 ​​

在运行时,我的类CSVProcessor接受一个函数对象,并在步骤2中使用它来处理步骤1中输出的每个元素。它只是将来自该函数的结果聚合到一个数组中,并继续进行操作。第3步。
示例代码(经过简化,但给出了一个主意):

class CSVProcessor:
    ...
    def step_1(self):
        self.data = self.extract_data_from_CSV()

    def step_2(self, processing_function):
        for element in self.data:
            element = processing_function(element)

    def step_3(self):
        self.update_database(self.data)

用法:

csv_proc = CSVProcessor()
csv_proc.step_1()
csv_proc.step_2(my_custom_function)         # my_custom_function would defined elsewhere
csv_proc.step_3()

解决方案2

我的类CSVProcessor定义了一个“抽象方法”,其目的是在该类的具体实现中处理单个元素。在运行时之前,CSVProcessor由新类继承,其抽象方法被覆盖以处理元素。

class CSVProcessor:
    ...
    def step_1(self):
        self.data = self.extract_data_from_CSV()

    def processing_function(self, element): # Abstract method to be overridden 
        pass

    def step_2(self):
        for element in self.data:
            element = self.processing_function(element)

    def step_3(self):
        self.update_database(self.data)

用法:

class ConcreteCSVProcessor:
    def processing_function(self, element): # Here it gets overridden
        # Do actual stuff
        # Blah blah blah

csv_proc = ConcreteCSVProcessor()
csv_proc.step_1()
csv_proc.step_2()                           # No need to pass anything!
csv_proc.step_3()

事后看来,这两个解决方案共享完全相同的工作流程,我的问题更像是“数据处理功能应驻留在哪里?”。
在C ++中,我显然会采用第二种解决方案,但是Python中的两种方法都一样容易实现,除了上面提到的以外,我并没有真正看到它们之间的明显差异。

今天还有一种事情,就是考虑一个人或多或少地使用Pythonic的方式...:p

0 个答案:

没有答案