2009-08-25 1 views
0

Quantitiesを使用してユニットと一緒に番号を定義することを検討しています。この値は、おそらくディスクに保存する必要があります。ご存知のように、酸洗処理には大きな問題があります:モジュールを再配置すると、パンチングはクラスを解決することができなくなり、情報をアンピクルすることができなくなります。この動作の回避策がありますが、実際には回避策です。安定したPythonのシリアル化(pickleモジュールの再配置の問題はありません)

私はこの問題のために幻想化した解決策は、特定の単位を一意にエンコードする文字列を作成することです。このエンコーディングをディスクから取得すると、Quantitiesモジュールのファクトリメソッドに渡され、Quantityモジュールが適切なユニットインスタンスにデコードされます。利点は、たとえモジュールを再配置しても、マジックストリングトークンをファクトリメソッドに渡す限り、すべてが機能することです。

これは既知の概念ですか?

答えて

1

ウィーラーの第一原理の応用のように見えます。「コンピュータサイエンスのすべての問題は別のレベルの間接指向で解決できます」(第二原理は「通常、別の問題を生み出します。基本的には、タイプを識別するための間接指定です。エンティティ内の型は、酸洗いのようなアプローチで問題ありません(後者の詳細については、pickle.pycopy_reg.pyのソースを調べることができます)。

具体的には、サブクラスpickle.Picklerを指定し、save_instメソッドをオーバーライドするとします。現在のバージョンは言うどこ:

if self.bin: 
     save(cls) 
     for arg in args: 
      save(arg) 
     write(OBJ) 
    else: 
     for arg in args: 
      save(arg) 
     write(INST + cls.__module__ + '\n' + cls.__name__ + '\n') 

あなただけのクラスのモジュールと名前よりも別の何か書きたい - おそらくあなた自身のレジストリで開催され、クラス(2つの文字列で構成)は、一意の識別子のいくつかの種類をまたはレジストリ。方法についても同様である。

_instantiate一部はすでに、独自の方法で因数分解されるので、それはUnpicklerのサブクラスのためにさらに簡単です:あなただけfind_classをオーバーライドする必要が、ある:

def find_class(self, module, name): 
    # Subclasses may override this 
    __import__(module) 
    mod = sys.modules[module] 
    klass = getattr(mod, name) 
    return klass 

それは二つの文字列とリターンを取る必要がありますクラスオブジェクト。あなたはあなたの登録簿を通してそれをもう一度行うことができます。

レジストリが関わっている場合と同様に、関心のあるすべてのオブジェクト(クラス)を登録する方法について考える必要があります。ここでの人気の戦略の1つは、酸漬けだけを残すことですが、 、モジュールの名前の変更などはどこかに永久に記録されます。このようにして、サブクラス化されたunpicklerはすべての作業を行うことができ、オーバーライドされたfind_classで最も便利にすべての問題を回避することができます。私はこれを「回避策」とみなしますが、私にとっては、「もう一つの問題」を避ける「間接指導のもう一つのレベル」という概念を、非常にシンプルでパワフルで便利に実現しているように思われます。

関連する問題