我想做的事情在功能上很容易编码,但我正在寻找一种清晰且可扩展的方式来组织这个......"美丽胜过丑陋。"
我有一个应用程序,我们从几个不同的地方收集有关项目的信息。收集原始数据后,我们需要从这些数据中提取许多属性。
项目数据的界面应该像简单的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的应用程序中留下的。
答案 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]