封装与继承,有助于做出选择

时间:2009-04-12 20:32:47

标签: python design-patterns inheritance abstract-class

我需要为几种不同的案例类型编写处理程序(在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:必须使用Handler_Case1实例作为第一个参数调用未绑定方法handleStuff()(改为使用tuple实例)

另一种选择是模仿抽象函数,如here所示(“问:你能用0行代码在Python中实现抽象类吗?”):

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. 这两种方法中哪一种更具pythonic? 和
  2. 如何实施第一个?

1 个答案:

答案 0 :(得分: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()