2016-11-28 4 views
0

私がしようとしていることは機能的にはコード化するのは簡単ですが、これを整理するためのクリーンでスケーラブルな方法を探しています...「美しいものは醜いよりも優れています。いくつかの大きなデータソースからデータを抽出する(多くの)方法を整理するにはどうすればよいですか?

私はいくつかの異なる場所からアイテムについての情報を収集するアプリケーションを持っています。生データが収集されたら、このデータから多くの属性を抽出する必要があります。

アイテムのデータへのインターフェイスは、簡単な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

私はあなたのソースを個別のロジックとして抽出し、それを別のクラスとして実装することができると思います。

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] 
+0

...私はアウトソースを壊す好きです関連するメソッドを使用してそのソースのデータから属性を抽出する独自のクラスに変換します。しかし、私は、インターフェイスの 'ItemData'クラスが属性のすべてのソースを調べるのが好きであるとは確信していません。それは確かにそれを行う一つの方法です。私は、データソースクラスをインターフェイスクラスに動的に登録し、提供できる属性を「ロード」できるようにする方法を検討しています。 – cmlccie

+0

私はあなたを正しく理解していれば、モデル 'DataSource'にデータをロードする動的な方法を実装するのは簡単です。私は私の答えを付け加えました。 – Fomalhaut

+0

私は、スケーラビリティを向上させるために、DataSourcesにItemDataクラスでその属性を動的に登録させることを指しています。基本的には、追加のデータソースを追加するときに必要な変更を最小限に抑えようとしています。追加の属性を提供する追加のDataSourceを追加するのに必要な最小限の作業で、ItemDataクラスを通じて 'すべての属性'を使用できます。 – cmlccie

関連する問題