ウィーラーの第一原則の適用のように見えます。「コンピューター サイエンスのすべての問題は、別のレベルの間接化によって解決できます」(第 2 原則は、「しかし、それは通常、別の問題を引き起こす」と付け加えています;-)。基本的に、型を識別するための間接化が必要です。entity-within-type は、酸洗のようなアプローチで問題ありません (後者のソースpickle.py
とすべての詳細を調べることができます)。copy_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 つの文字列で構成される) を書きたいとします。おそらく、独自のレジストリまたはレジストリに保持されます。メソッドについても同様ですsave_global
。
のサブクラスにとってはさらに簡単です。Unpickler
なぜなら、その_instantiate
部分はすでに独自のメソッドで分解されているからです。オーバーライドする必要がfind_class
あるのは、次のとおりです。
def find_class(self, module, name):
# Subclasses may override this
__import__(module)
mod = sys.modules[module]
klass = getattr(mod, name)
return klass
2 つの文字列を取り、クラス オブジェクトを返す必要があります。これもレジストリを介して行うことができます。
レジストリが関係する場合は常にそうであるように、関心のあるすべてのオブジェクト (クラス) を確実に登録する方法などを考える必要があります。ここでの一般的な戦略の 1 つは、ピッキングをそのままにしておくことですが、クラスのすべての移動、モジュールの名前変更を確実にすることです。などは、永続的な場所に記録されます。このように、サブクラス化された unpickler だけがすべての作業を行うことができfind_class
、登録のすべての問題をバイパスして、オーバーライドされた状態ですべての作業を最も便利に行うことができます。これを「回避策」と考えていると思いますが、私には、「もう1つの問題」の問題を回避する「もう1つのレベルの間接化」概念の非常にシンプルで強力で便利な実装のように思えます;-)。