Дизайн Python: ООП - PullRequest
       4

Дизайн Python: ООП

4 голосов
/ 17 октября 2011

Я пытаюсь сделать что-то вроде этого:

class A:

    def __init__( self, x=None, y=None ):
        self.x = x
        self.y = y

class B( A ):

     def do_something_in_Bs_context( self ):
         print "In B"

class C( A ):

    def do_something_in_Cs_context( self ):
        print "In C"


a = A(1,2)
b = B.do_something_in_Bs_context( a )
c = C.do_something_in_Cs_context( a )

Как и ожидалось, этот код выдаст эту ошибку:

TypeError: unbound method do_something_in_Bs_context() must be called with B instance as first argument (got A instance instead)

Основная причина этой схемы заключается в том, что A - это контейнер данных (скажем, таблица), а B и C - это набор операций над A. И B, и C работают с одними и теми же данными, но концептуально представляют собой отдельный набор операции, которые могут быть выполнены на тех же данных. Я мог бы объединить все операции в B и C внутри A, но я хочу создать разделение по понятиям. (Например, на столе я могу выполнить различные наборы операций, которые можно сгруппировать, скажем, в исчисление или тригонометрию. Итак, A: таблица, B: исчисление, C: тригонометрия)

Это немного напомнило мне парадигму Model-View-Controller.

Я предложил следующие решения:

  1. B и C реализованы как концептуально разные классы ( View / Controller), которые поддерживают ссылку на экземпляр A и работать на этом экземпляре.
  2. Так как B и C просто группируются методы на A, создавать модули с функциями, которые работают на экземпляр А.

Мне не очень нравится ни одно из этих решений (2 немного лучше, чем 1), но тогда я не уверен, что есть лучший / чище / более питонический способ решения этой проблемы. Есть указатели?

Ответы [ 2 ]

6 голосов
/ 17 октября 2011

Вот как я понимаю вопрос: B и C - это наборы функций, которые используют данные типа A. То, что вы хотите сделать, это сгруппировать функции логически.

Я бы предложил сделать одно из следующих действий:

  1. разделяет функции на классы B и C, которые работают с A - это отношение HAS-A. Функции / методы могут быть статическими, если это то, что вам нужно
  2. разделяет функции на модули B и C, создавая определения функций верхнего уровня

Я думаю, что наследование было бы плохим решением этой проблемы. Я не думаю, что есть отношения IS-A.

1 голос
/ 17 октября 2011

Переместить состояние в дополнительный класс и сделать его экземпляр атрибутом A:

class State(object):
    def __init__( self, x=None, y=None ):
        self.x = x
        self.y = y

class A(object):
    def __init__( self, state=None ):
        self.state = state

class B( A ):
    def __init__( self, state=None ):
        super(B, self).__init__(state)

    def do_something_in_Bs_context( self ):
        print self.state.x

class C( A ):
    def __init__( self, state=None ):
        super(C, self).__init__(state)

    def do_something_in_Cs_context( self ):
        print self.state.y

s = State(1, 2)
b = B(s)
c = C(s)
b.do_something_in_Bs_context()
c.do_something_in_Cs_context()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...