2009-04-12 4 views
1

Мне нужно написать обработчики для нескольких типов case (в Python). Интерфейс для всех этих типов один и тот же, но логика обработки отличается.Инкапсуляция против наследования, помощь в выборе

Одним из вариантов определения общего класса, который принимает конкретный тип обработчика в качестве одного из параметров __init__:

class Handler: 
    def __init__ (self, handlerType): 
     self._handlerType = handlerType 
     self._handler = handlerType.handleStuff 

    def handleStuff(self, *args, **kwargs): 
     return self._handler(args, kwargs) 


# case specific handlers 

class Handler_Case1: 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 1' 


class Handler_Case2: 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 2' 



if __name__ == '__main__': 
    handlers = [] 
    handlers.append(Handler(Handler_Case1)) 
    handlers.append(Handler(Handler_Case2)) 
    for h in handlers: 
     h.handleStuff() 

Однако, это приводит к TypeError:

TypeError: unbound method handleStuff() must be called with Handler_Case1 instance as first argument (got tuple instance instead)

Другой вариант для имитации абстрактной функции, как показано на рисунке here («Q: Можете ли вы реализовать абстрактные классы в Python в 0 строках кода?»):

class Handler: 
    def handleStuff(self, *args, **kwargs): abstract 
    def commonFunction(self): 
     print 'Common function' 


# case specific handlers 

class Handler_Case1(Handler): 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 1' 


class Handler_Case2(Handler): 
    def handleStuff(self, *args, **kwargs): 
     print 'Handling Case 2' 



if __name__ == '__main__': 
    handlers = [] 
    h1 = (Handler_Case1()) 
    h2 = (Handler_Case2()) 
    handlers.append(h1) 
    handlers.append(h2) 
    for h in handlers: 
     h.handleStuff() 
     print 

Таким образом, на самом деле, у меня есть два вопроса:

  1. Какой из этих двух подходов является более вещим? и
  2. Как реализовать первый вариант?

ответ

4

я может отсутствовать некоторые тонкие хитросплетения в вашем вопросе, но, учитывая ваш первый пример, то, что мешает вам делать что-то вроде этого:

class HandlerCase1(object): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 1" 


class HandlerCase2(object): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 2" 


if __name__ == "__main__": 
    handlers = [] 
    handlers.append(HandlerCase1()) 
    handlers.append(HandlerCase2()) 
    for h in handlers: 
     h.handle_stuff() 

И если вы хотите, чтобы классы разделить некоторые общие (базы), есть ли что-то, что вас удерживает:

class Handler(object): 
    def common_function(self): 
     print "Common function" 


class HandlerCase1(Handler): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 1" 


class HandlerCase2(Handler): 
    def handle_stuff(self, *args, **kwargs): 
     print "Handling case 2" 


if __name__ == "__main__": 
    handlers = [] 
    handlers.append(HandlerCase1()) 
    handlers.append(HandlerCase2()) 
    for h in handlers: 
     h.handle_stuff() 
     h.common_function() 
Смежные вопросы