dict作为参数化python类的方法的替代方法是什么?

时间:2018-09-04 17:58:52

标签: python class dictionary

我通常会在所使用的代码库周围看到以下python代码:

class A:
    def do_something(self):
        pass

class B:
    def do_something(self):
        pass


class C:
    _magic_dict = {'option1' : A, 'option2' : B}

   def do_something_else(self, option):
       # call some other methods, functiosn
       my_option = _magic_dict['option']()
       my_option.do_something()

       self.do_more_things(my_option)

因此,基本思想是使C类对A或B通用。 这是常见的做法吗?我觉得这是对指令的过度使用,而且一切(在本例中为类)都是可以传递的对象。

对于更具体的问题,以下示例可能会有所帮助。有一个类负责获取给定的度量标准对象,该类最终是持有该度量标准类型信息的对象的字典。有一个统计报告器,它将使用给定的度量对象,选择要报告的数据类型(假设是dict中的一项),并以漂亮的格式输出。所以:

class FoodMetric:
    def __init__(self, path_to_my_stock_files):
        self._path = path_to_my_stock_files
        self._data = {}

    def parse(self):
        # let's assume that after parsing the files, the following data would have been obtained:
        # self.data = {'cheese' : {'cheddar' : 10, 'goat' : 20}}

class WoodFastenerMetric:
    def __init__(self, path_to_my_stock_files):
        self._path = path_to_my_stock_files
        self._data = {}

    def parse(self):
        # let's assume that after parsing the files, the following data would have been obtained:
        # self.data = {'nails' : {'round' : 10, 'oval' : 20}}

class StatsReporter:

    _magic_dict = {'food' : (FoodMetric, ['column1', 'column2'], 'cheese')
                   'wood_fastener' : (WoodFastener, ['columnA', 'columnB'], 'nail')
                  }      

    def present_data(metric_type):
        the_class, columns, data_set_name = _magic_dict(metric_type)
        metric = the_class(self._path) # assume I have the path for the files here
        metric.parse()
        print(self._convert_to_table(metric, columns, data_set_name))

我确实有一个替代实现,可以通过将A或B的一个实例传递给C来创建C,因此消除了在C内部进行此字典查找的过程。

还有哪些其他选择,或者问题中所述的解决方案是在python中解决此问题的常用方法?

P.S .:我希望这个例子能使意图更加清楚。

1 个答案:

答案 0 :(得分:2)

使用与原始问题相同的类和方法名称,并且缺少有关要解决的实际问题的任何信息,我将代码重构为以下内容:

class C:
   def do_something_else(self):
       self.do_something()
       self.do_more_things()

    def do_something(self):
        raise NotImplementedError()

class A(C):
    def do_something(self):
        pass

class B(C):
    def do_something(self):
        pass

def make_instance(option):
    return {'option1' : A, 'option2' : B}[option]()

instance = make_instance(option)
instance.do_something_else()

通过这种方法,设计很清晰:C实现了通用功能,而AB是其专门技术。

剩下的唯一一个 ugly 部分是make_instance函数,它可能也可以更好,但不是问题的表达方式,因为尚不清楚{{1}的位置}来自。