类可以从不同的文件继承方法(或子类)吗?这是" Pythonic"?

时间:2017-01-09 11:22:33

标签: python class oop inheritance

在尝试构建科学的Python包时,为了清晰起见,我的目标是将关键功能分成不同的.py文件。具体来说,将模型的复杂数值计算分解为一个python文件(例如," processing.py"),并将其可视化的例程绘制到另一个python文件("绘图)似乎是合乎逻辑的。的.py"。)

为了方便和节省内存的使用,模型类应该能够继承所有绘图方法,使用户可以轻松访问它们,同时通过将科学数字代码与可视化代码分离,使代码易于维护和读取。

我概述了我在下面实现这一目标的愿景,但我正在努力解决如何在Python中实现这一点/如果有更好的OOP风格。

例如,在plotting.py中:

class ItemPlotter(object):

    def visualisation_routine1(self):
        plt.plot(self.values)  # where values are to be acquired from the class in processing.py somehow

并在processing.py中:

class Item(object):

    def __init__(self, flag):
        if flag is True:
            self.values = (1, 2, 3)
        else:
            self.values = (10, 5, 0)

        from plotting.py import ItemPlotter
        self.plots = ItemPlotter()

导致以下命令行用法:

 from processing.py import Item
 my_item = Item(flag=True)
 # Plot results
 my_item.plots.visualisation_routine1()

我的实际代码会比这更复杂,并且可能Item会有大数据集的属性,因此我希望我不要为了内存效率而避免复制这些属性。

我的视力是否可行,甚至是Pythonic方法? 任何评论重新。 OOP或实现这一目标的有效方法将不胜感激。

PS,我的目标是兼容Py2.7和Py3。

1 个答案:

答案 0 :(得分:1)

  

为了方便和节省内存的使用,模型类应该能够继承所有绘图方法,使用户可以轻松访问它们,同时通过将科学数字代码与可视化代码分离,使代码易于维护和读取。

正如Jon指出的那样,你实际上是在描述构图而不是继承(无论如何都是generally preferred这种方式。)

实现目标的一种方法是创建一个抽象类,用于定义“项目绘图仪”的界面,并inject it as a dependency创建Item的实例。您可以允许Item的客户端通过将委托绘图的方法公开给注入的Item来轻松绘制ItemPlotter实例封装的数据。

此方法允许每个类尊重Single Responsibility Principle并使代码更易于理解,维护和测试。如果您愿意,可以在单独的Python模块中定义ItemItemPlotter

from abc import abstractmethod, ABC


class AbstractItemPlotter(ABC):
    @abstractmethod
    def plot(self, values):
        return


class ItemPlotter(AbstractItemPlotter):
    def plot(self, values):
        # plt.plot(values)
        print('Plotting {}'.format(values))
        pass


class Item(object):
    def __init__(self, flag: bool, plotter: AbstractItemPlotter):
        self._plotter = plotter
        if flag:
            self.values = (1, 2, 3)
        else:
            self.values = (10, 5, 0)

    def visualisation_routine1(self):
        self._plotter.plot(self.values)

if __name__ == '__main__':
    item = Item(flag=True, plotter=ItemPlotter())
    item.visualisation_routine1()

<强>输出

Plotting (1, 2, 3)

修改

此代码使用Python 3.5.2进行了测试。我不能肯定地说它是否可以在Python 2.7中运行。