あなたは、データの最も重要な部分、つまりデータの形について話すことを怠りました。それは本当にここで最も重要なことです。 「デザインパターン」は気を散らすものです。これらのパターンの多くは、Pythonにはない言語の制限があり、不必要な剛性をもたらすために存在します。
- まず、データの形状を調べます。例:????
- まず、XMLは、XMLから抽出されたデータの一部収集(簡易辞書ネストされた辞書データはあなたが必要なのですか何が、それは均質または不均質です。これは、最も重要なその後
- あなたが持っている
持っていますあなたはそれについて話しません!)
- 次に、このデータをSQLバックエンドでシリアル化/永続化します。
- 次に、そのデータの操作を容易にするために、メソッド、プロパティ、またはdictまたはtuple内の単なる項目の「インターフェース」(口頭での説明)を設計します。シンプルなままにして、ネイティブのPython型に固執すれば、クラス、関数、ディクテーション/タプルは必要ないかもしれません。
- アプリケーションに必要な抽象レベルが得られるまで、反復処理を繰り返します。
たとえば、「抽出者」のインターフェイスは「xml文字列を生成する反復可能」である可能性があります。これは、__iter__
とnext()
メソッドを持つクラスまたはクラスのいずれかになります。抽象クラスを定義し、それをサブクラス化する必要はありません!
データに追加できる構成可能なポリモーフィズムの種類は、データの正確な形状によって異なります。たとえば、あなたは規則を使用することができます。
# persisters.py
def persist_foo(data):
pass
# main.py
import persisters
data = {'type':'foo', 'values':{'field1':'a','field2':[1,2]}}
try:
foo_persister = getitem(persisters, 'persist_'+data['type'])
except AttributeError:
# no 'foo' persister is available!
それとも、(多分あなたはあなたがコントロールすることはできません新しいモジュールを追加する必要があります)、さらに抽象化が必要な場合、あなたは(あるだけのdict)レジストリおよびモジュールを使用することができます大会:
# registry.py
def register(registry, method, type_):
"""Returns a decorator that registers a callable in a registry for the method and type"""
def register_decorator(callable_):
registry.setdefault(method, {})[type_] = callable_
return callable_
return register_decorator
def merge_registries(r1, r2):
for method, type_ in r2.iteritems():
r1.setdefault(method, {}).update(r2[method])
def get_callable(registry, method, type_):
try:
callable_ = registry[method][type]
except KeyError, e:
e.message = 'No {} method for type {} in registry'.format(method, type)
raise e
return callable_
def retrieve_registry(module):
try:
return module.get_registry()
except AttributeError:
return {}
def add_module_registry(yourregistry, *modules)
for module in modules:
merge_registries(yourregistry, module)
# extractors.py
from registry import register
_REGISTRY = {}
def get_registry():
return _REGISTRY
@register(_REGISTRY, 'extract', 'foo')
def foo_extractor(abc):
print 'extracting_foo'
# main.py
import extractors, registry
my_registry = {}
registry.add_module_registry(my_registry, extractors)
foo_extracter = registry.get_callable(my_registry, 'extract', 'foo')
したい場合(あなたはそれが少し不便だ場合でも、グローバルな状態を避けるべきであるが。)あなたは簡単にこのような構造の上にグローバルなレジストリを構築することができます
をあなたが公共のフレームワークを構築している場合最大限の拡張性と形式性が必要です。あなたは複雑さを支払うことを喜んで、あなたはzope.interface
のようなものを見ることができます。 (これはPyramidで使用されています)
独自の抽出変換ロードアプリケーションをロールバックするのではなく、scrapyと考えましたか? scrapyを使用すると、文字列が与えられ、アイテム(データ)またはリクエスト(フェッチするURLなど、より多くの文字列のリクエスト)のシーケンスを返す「Spider」を作成します。アイテムは、それが渡される前に受信するアイテム(例えば、DBに保持されているアイテム)で何をしても構わない、構成可能なアイテムパイプラインを介して送信される。
Scrapyを使用しない場合でも、データ中心のパイプライン型の設計を採用し、具体的な「クラス」と「パターン」の代わりに抽象的な「呼び出し可能」と「反復可能」なインタフェースを考えてください。
あなたはデータベースにfetcher_dictを入れることもできますので、コードを変更する必要はありません(もちろんフェッチャーコード以外) – RickyA
@ mgilsonは私の心を読みます。デザインパターンに多大な労力を費やすことはありません。それらはコード設計の点で過大評価されています。特定の問題を解決するためのポインタとしてそれらを参照してください。あなたの周りにあなたのデザインを構築しないでください。さもなければ、コードの判読不能な混乱に終わるでしょう。私はそれを何度も見てきました。 – RickyA
マップは偽装されたswitch文です) – atamanroman