如何组织(许多)从几个较大的数据源中提取数据的方法?

时间:2016-11-28 04:57:01

标签: python python-2.7 python-3.x methods

我想做的事情在功能上很容易编码,但我正在寻找一种清晰且可扩展的方式来组织这个......"美丽胜过丑陋。"

我有一个应用程序,我们从几个不同的地方收集有关项目的信息。收集原始数据后,我们需要从这些数据中提取许多属性。

项目数据的界面应该像简单的dict一样工作,使用友好的密钥名称访问属性。我知道我可以通过subclassing one of the ABCs from the collections module完成此任务。

我的问题是:我如何(干净地)组织提取数据属性所需的许多功能?

我可以使用缓存属性...将数据源和提取函数分解为单独的模块/类...

我考虑将所有这些内容放在一个类中,如下所示:

class item_data(object):

    def __init__(self, item_name):
        self.name = item_name
        self._item_data = {'name': item_name}
        self._data_a = _get_data_from_source_a()
        self._data_b = _get_data_from_source_b()

    def _get_data_from_source_a(self):
        pass

    def _get_data_from_source_b(self):
        pass

    def _extract_attr_1(self):
        # Extract some data attribute from _data_a
        pass

    def _extract_attr_2(self):
        # Extract some data attribute from _data_a
        pass

    def _extract_attr_3(self):
        # Extract some data attribute from _data_b
        pass

    _attr_extract_methods = {
        'Attribute 1': _extract_attr_1,
        'Attribute 2': _extract_attr_2,
        'Attribute 3': _extract_attr_3,
    }

    def __getitem__(self, item):
        if item not in self._item_data:
            self._attr_extract_methods[item](self)
        return self._item_data[item]

如果我想将数据源(以及相关的属性提取函数)分解为它们自己的模块/类,我该如何以干净和可扩展的方式这样做,以便以后可以轻松添加新的数据源和属性?有没有办法让数据源类能够在顶级类中注册自己及其相关属性?

注意:这是在支持Python v2.7 +和v3.x的应用程序中留下的。

1 个答案:

答案 0 :(得分:0)

我认为您可以将源提取视为单独的逻辑并将其作为单独的类实现。这看起来像这样:

class DataSource(object):
    def load(self):
        # do loading

    def __getitem__(self, item):
        if item == "Attribute 1":
            return ...
        elif item == "Attribute 2":
            return ...
        elif ...


class ItemData(object):
    def __init__(self, name):
        self.name = name
        self._data = {'name': name}
        self._source = DataSource()
        self._source.load()

    def __getitem__(self, item):
        if item not in self._data:
            return self._source[item]
        else:
            return self._data[item]

如果您应该使用非常不同的逻辑从源中加载attribultes,也许最好为每个属性使用单独的类:

class BaseSourceAttribute(object):
    def load(self):
        raise NotImplementedError()


class Attribute1(BaseSourceAttribute):
    def load(self):
        return "1"


class Attribute2(BaseSourceAttribute):
    def load(self):
        return "2"


class DataSource(object):
    attributes = {
        'attr1': Attribute1(),
        'attr2': Attribute2()
    }

    def __init__(self):
        self._data = {}

    def load(self):
        for item, attr_obj in self.attributes.items():
            self._data[item] = attr_obj.load()

    def __getitem__(self, item):
        return self._data[item]


class ItemData(object):
    def __init__(self, name):
        self.name = name
        self._data = {'name': name}
        self._source = DataSource()
        self._source.load()

    def __getitem__(self, item):
        if item not in self._data:
            return self._source[item]
        else:
            return self._data[item]

对于动态加载源,您可以像这样修改类DataSource,例如:

class DataSource(object):
    attributes = {
        'attr1': Attribute1(),
        'attr2': Attribute2()
    }

    def __init__(self):
        self._data = {}

    def load(self):
        pass

    def __getitem__(self, item):
        if item not in self._data:
            self._data[item] = self.attributes[item].load()
        return self._data[item]