Предотвращение дублирования кода внутри классов Python

#python #python-3.x #oop #inheritance

#python #python-3.x #ооп #наследование

Вопрос:

Вот часть моего кода:

 class classA(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
         Some Unique Code
         .
         .
         .
         .
         Some Common Code

class classB(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
         Some Unique Code
         .
         .
         .
         .
         Some Common Code
 

Some Common Code Часть состоит из более чем 200 строк, и она абсолютно одинакова в обоих classA и classB . Я должен создать 5 или более таких классов. Это приведет к большому дублированию.

Обновление: Some Common Code части состоят из множества циклов и других функций, которые полагаются на данные из Some Unique Code .

Обновление после решения Рафаэля: в и есть несколько общих переменных classA classB . Эти переменные используются как внутри «общего кода», так и в «уникальном коде». Перемещение их из одного класса в другой создает переменные undefined ошибки.

Вот мой код после обновлений:

 class Something(Else):
      
      CONFIG = {
          "alpha": "beta"
      }

      def setup(self):
            // Some Code
            return self

      def common_method(self):

            for i in texts:
                  // Manipulates Boxes

class classA(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
         texts = []

         texts.append('Apple')
         .
         .
         .
         .
         self.common_method()

class classB(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
         texts = []

         texts.append('Mango')
         .
         .
         .
         .
         self.common_method()
      
 

Я новичок в Python, поэтому я не знаю, как я могу избежать этого дублирования. Любая помощь будет оценена.

Спасибо.

Комментарии:

1. Является ли добавление метода «common_method» к родительскому классу «Something» опцией? Затем вы можете вызвать «common_method» вместо написания «Некоторого общего кода»

2. «Общий код» в основном состоит из for циклов и других методов Something класса. Будет ли это проблемой?

3. вовсе нет. Я опубликовал пример.

Ответ №1:

В качестве альтернативы ответу @Raphael мы можем сосредоточиться на методе «construct» и придумать такую структуру:

 class Something:

    def common_method(self):
        """ """

    def construct(self):
        self.common_method()


class ClassA(Something):

    def construct(self):
        # A-specific code
         super().construct()


class ClassB(Something):

    def construct(self):
        # B-specific code
         super().construct()
 

, но трудно сказать, что будет лучше, без более подробной информации.

ОБНОВЛЕНИЕ: если вам нужно манипулировать общими переменными наряду с различными методами, вам нужно установить их как object attributes (или class attributes ).

В python есть специальный метод, __init__ который используется для создания объекта.

Вот пример для вашего случая:

 class Something(Else):

    def __init__(self):
        self.texts = []
        
    CONFIG = {
        "alpha": "beta"
    }

    def setup(self):
        # Some Code
        return self

    def common_method(self):

        # Manipulates Boxes
        for i in self.texts:
            pass


class classA(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
        self.texts.append('Apple')
        self.common_method()


class classB(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
        self.texts.append('Mango')
        self.common_method()
 

Комментарии:

1. Спасибо @hidden. 🙂 Я добавил обновление к вопросу на основе ответа Рафаэля. Решит ли ваш метод undefined ошибку переменной?

2. @RealNoob, обе предложенные структуры должны работать для вас. Покажите нам упрощенный пример вашего кода, чтобы мы могли понять, где вы допускаете ошибки.

3. Я постараюсь создать упрощенную версию и опубликовать ее в деталях вопроса. 🙂

4. Привет @hidden, не могли бы вы взглянуть на код сейчас? Спасибо.

5. Привет @hidden. Я получаю TypeError: __init__() got an unexpected keyword argument 'window_config' сообщение об ошибке с приведенным выше кодом.

Ответ №2:

Просто передайте «общий код» общему методу родительского класса

Примечание: если КОНФИГУРАЦИЯ также идентична для ваших подклассов, вы можете передать это также родительскому классу

 class Something:

    def common_method(self):
        pass  # common stuff
    

class ClassA(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
         self.common_method()
         ...
         self.common_method()


class ClassB(Something):

    CONFIG={
        "opt_a": "opt_b"
    }

    def construct(self):
         self.common_method()
         ...
         self.common_method()
 

Обновить:
Ошибка в вашем обновлении возникает из-за переменной «texts», которая не определена в общем методе.
Один из способов решить эту проблему — сделать texts переменной экземпляра.

 class ParentClass:
    
    def __init__(self):
        self.texts = []
    
    def common_method(self):
        for text in self.texts:
            print(text)

class classA(ParentClass):

    def construct(self):
        self.texts.append('Apple')
        ...
        self.common_method()
 

Комментарии:

1. Спасибо Рафаэлю. Я получаю ошибки о неопределенных переменных при перемещении переменных из родительского класса в дочерний или дочерний класс в родительский

2. @RealNoob трудно сказать, что происходит не так, без примера

3. Привет, @Raphael, не могли бы вы взглянуть на код сейчас? Спасибо.