Вложенные классы / функции, которые вызывают друг друга и должны наследовать свойства своих родителей - PullRequest
2 голосов
/ 05 мая 2020

У меня довольно странный сценарий, и я просто не могу придумать правильное решение. Я работаю над проектом, который имеет несколько функций для выполнения определенных операций:

  • Эти функции взаимосвязаны и должны иметь возможность вызывать друг друга (и наследовать параметры своего родительского объекта).
  • Каждая операция должна быть расширяемой и иметь возможность добавлять новые функции.
  • Для каждой операции должна быть функция по умолчанию.

Позвольте мне привести простой пример . Рассмотрим класс mymath, который может выполнять add и multiply. multiply может быть выполнено простым умножением или итеративным вызовом функции add (давайте представим, что оператор + не существует, чтобы продемонстрировать требование, чтобы функции могли вызывать друг друга). Вот пример использования вложенных классов:

class addition_N:
    def add(self, obj):
        result = obj.param1 + obj.param2
        return result

class multiply_N:
    def multiply(self, obj):
        return obj.param1 * obj.param2

    def mult_loop(self, obj):
        param1 = obj.param1
        obj.param1 = 0

        for i in range(param1):
            obj.param1 = getattr(mymath.addition, 'add')(self, obj=obj)

        return obj.param1

class mymath:
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2

    class multiply(multiply_N):
        def __new__(cls, obj, func="multiply"):
            return getattr(cls, func)(cls, obj=obj)

    class addition(addition_N):
        def __new__(cls, obj, func="add"):
            return getattr(cls, func)(cls, obj=obj)


math = mymath(param1=2, param2=3)
mult = math.multiply(math, func='multiply')

math = mymath(param1=2, param2=3)
mult_loop = math.multiply(math, func='mult_loop')

math = mymath(param1=2, param2=3)
add = math.addition(math, func='add')

print(mult)
print(mult_loop)
print(add)

(Пожалуйста, не убивайте меня за использование __new__. В моем реальном коде проекта есть несколько условных операторов для обработки различных сценариев ios. Если у вас есть предложения по дополнительным альтернативам Pythoni c, дайте мне знать - я могу изменить их в соответствии со своими потребностями).

Код легче расширить, но у меня есть проблема с определением объема. Чтобы решить проблему с областью видимости, я передаю весь объект obj каждой функции. Это работает, но беспорядочно. (Прежде чем предлагать мне просто скопировать параметры родительской функции и создать экземпляры новых объектов, мой фактический проект довольно сложен, имеет МНОГО параметров, а это убивает производительность).

Что мне не хватает, Вот? Я чувствую, что прямо у меня под носом есть простое решение, но я так долго смотрел на свой код, что не могу его понять.

EDIT 2020-05-04 Я удалил вызовы eval из своего примера. Я не знал об использовании getattr. Я все еще не уверен, как справиться с проблемой определения объема.

РЕДАКТИРОВАТЬ 2020-05-05 Я разбил вещи на подклассы. Это больше соответствует моей конечной цели. Пользователям будут предоставлены классы _N для расширения, а код будет включен в мой основной класс mymath во время выполнения.

Я до сих пор не могу найти хороший способ обойти область видимости проблема с obj, однако. Мысли?

...