Добавление вместе одинаково структурированных классов - PullRequest
0 голосов
/ 28 января 2020

Для некоторых программ мне нужно сложить различные части (длинных) уравнений, которые зависят от множества параметров. До недавнего времени я создавал класс для каждой комбинации всех уравнений, что приводит к большому количеству операций копирования и вставки, от которых я хочу избавиться.

Общая настройка иллюстрируется следующим минимальным примером ниже:

  • Каждая часть уравнения имеет некоторую похожую структуру (здесь она описывается переменной par_1 и функцией func); о них заботятся в AB C.
  • Некоторые параметры (например, par_2) и функциональные формы не разделяются между разными частями (тип возврата func одинаков для всех подклассов) ,

Мое предлагаемое решение для обхода копирования и вставки состояло бы в том, чтобы просто ввести и добавить оператор между экземплярами класса, как показано в коде. В то время как для этого простого примера все работает хорошо, я не уверен, насколько обобщенная структура будет обобщена, или есть ли лучший стиль для выполнения sh.

from abc import ABC, abstractmethod

##################################
### These are the base classes ###
################################## 
class Base(ABC):
    def __init__(self, par_1):
        self.par_1 = par_1

    def __add__(self, other):
        return CombinedBase(self, other)

    @abstractmethod  
    def func(self, num):
        raise NotImplementedError("To be implemented")


class CombinedBase(Base):

    def __init__(self, instA, instB):
        assert(instA.__class__.__base__.__name__ == "Base")
        assert(instB.__class__.__base__.__name__ == "Base")
        self.instA = instA
        self.instB = instB

    def func(self, num):
        return self.instA.func(num) + self.instB.func(num)

#############################################
### These are some placeholder subclasses ###
#############################################
class ClsA(Base):
    def __init__(self, par_1, par_2):
        super().__init__(par_1)
        self.par_2 = par_2

    def func(self, num):
        return 2.*self.par_1 + self.par_2 + 2.*num

class ClsB(Base):
    def __init__(self, par_1, par_2):
        super().__init__(par_1)
        self.par_2 = par_2

    def func(self, num):
        return 1.*self.par_1 * self.par_2 - num

#################################
### Example with some numbers ###
#################################
par_1 = 15.
par_2 = 37.
par_3a = 4.
par_3b = 8.
num = 11.

instA = ClsA(par_1,par_2)
instB1 = ClsB(par_1,par_3a)
instB2 = ClsB(par_1,par_3b)
combined =  instA + instB1 + instB2

res_direct = instA.func(num) + instB1.func(num) + instB2.func(num)
res_combined = combined.func(num)
res_direct == res_combined # Gives True
...