接口与抽象基类
接口与抽象基类
对于Python的抽象基类,知乎上的一个例子是
当你开发一个项目或服务,你需要给上下游的组件提供接口。让别人来调用你的程序接口,上下游组件该怎么样才能达到想要的目的和你的组件无缝衔接?需要通过按照你接口中规定的抽象方法来实现,例如,你提供一个访问网络请求的接口,你不会去实现host、username、password的注册和发送请求,这些需要调用的用户去实现,你只需要规定:“调用者必须实现指定方法才能实现调用”即可。
实际上在科学计算里这种需求.. 比如要实现一类混合模拟,他们求解的方程、求解方式都不同,但是都能给出同一物理量的结果. 比如A区域求解玻尔兹曼方程,可能采用离散坐标或者蒙特卡洛来求解. B区域求解扩散方程,可能用有限元或者有限差分来求解. 在迭代过程中,我们需要每一步都执行两个区域的模拟,通过他们中间的overlap区域来实现信息交换或判断收敛. 算法、区域都可能不同,但是核心迭代的流程应该都是类似的,我们怎么针对这种需求提供统一的接口?似乎Python的抽象基类也是一个可以接受的选择..
比如下面我们定义了一个Hybrid类,A_obj
可能类似于上面左侧红框的模拟区域对象,B_obj
类似于中间的蓝色模拟区域对象,他们两个组合成了一个hybrid对.
1 | class Hybrid(object): |
A_obj和B_obj都是抽象基类Simulation的子类,Simulation类定义了几个抽象方法以用作统一接口,比如求解、返回结果,具体怎么求解、不同模拟方法经过怎样的后处理才能返回同一宏观量的分布,抽象基类不去定义,但是它的子类必须给出实现.
1 | import abc |
比如我可以直接建立一个FEM类,这个类就是接受建立好的Comsol对象,求解过程直接调用Comsol接口的run
方法,返回求解结果调用mph库的evaluate
方法.
1 | import mph |
把这个符合接口的FEM类的对象丢到Hybrid里,就可以去迭代了.