如何在Python中以有效的方式封装处理程序?

时间:2013-03-15 03:22:27

标签: python

我正在组建一个处理不同类型数据的处理程序。这是我目前的解决方案:

def get_handler_by_type(type):
    def handler_for_type_A:
        ...
        #code for processing data type A

    def handler_for_type_B:
        ...
        #code for processing data type B

    def handler_for_type_C:
        ...
        #code for processing data type C

    handler_map = {type_A: handler_for_type_A,
               type_B: handler_for_type_B,
               type_C: handler_for_type_C,
              }
    return handler_map(type)

但是,这似乎效率很低,因为我会经常调用get_handler_by_type,每次调用它时,都会再次构造字典。

我知道我可以这样做:

def handler_for_type_A:
    ...
    #code for processing data type A

def handler_for_type_B:
    ...
    #code for processing data type B

def handler_for_type_C:
    ...
    #code for processing data type C

handler_map = {type_A: handler_for_type_A,
                type_B: handler_for_type_B,
                type_C: handler_for_type_C,
            }

def get_handler_by_type(type, handler_map = handler_map):
    return handler_map(type)

但在我看来,这非常难看。因为我有handler_for_type_Xs和handler_map污染全局空间。有没有办法有效和优雅地做到这一点?

感谢您的任何意见。

2 个答案:

答案 0 :(得分:2)

一种方法是动态查找处理程序(如果您有一致的命名约定)

return vars()['handler_for_'+type]

另一种方法是将地图存储为函数的属性

def get_handler_by_type(type):
    def handler_for_type_A:
        ...
        #code for processing data type A

    def handler_for_type_B:
        ...
        #code for processing data type B

    def handler_for_type_C:
        ...
        #code for processing data type C

    if not hasattr(get_handler_by_type, 'handler_map'):
        get_handler_by_type.handler_map = {'type_A': handler_for_type_A,
               'type_B': handler_for_type_B,
               'type_C': handler_for_type_C,
              }

    return get_handler_by_type.handler_map[type]

答案 1 :(得分:1)

这种方法将封装它:

def _handler_helper():
   def fna():
      print "a" 
      pass

   def fnb():
      print "b" 
      pass

   m = {"a":fna,"b":fnb}
   return lambda x:m[x]

get_handler_by_type = _handler_helper()

如果您想拥有文档字符串,可能需要使用def,但这样可以。

另一种选择可能是采用更多的OOP方法:

class _HandlerHelper:
   def fna(self):
       print 'a'

   def fnb(self):
       print 'b'

   # __call__ is a magic method which lets you treat the object as a function
   def __call__(self, fn):
       return getattr(self, 'fn' + fn)

get_handler_by_type = _HandlerHelper()