2011-01-03 12 views
3

私はPythonの "units"パッケージ(http://pypi.python.org/pypi/units/)を使用しています。それらをピケットしようとするといくつか問題が発生しました。私は何が起こっているのかを試してみるために、可能な限り簡単にそれを煮詰めようとしました。ここに私の簡単なテストです:pythonの "units"単位をpickleすることは可能ですか?

from units import unit, named_unit 
from units.predefined import define_units 
from units.compatibility import compatible 
from units.registry import REGISTRY 

a = unit('m') 
a_p = pickle.dumps(a) 
a_up = pickle.loads(a_p) 

logging.info(repr(unit('m'))) 
logging.info(repr(a)) 
logging.info(repr(a_up)) 

logging.info(a.is_si()) 
logging.info(a_up.is_si()) 

logging.info(compatible(a,a_up)) 
logging.info(a(10) + a_up(10)) 

私はこれを実行すると、私は見ている出力は次のようになります。

LeafUnit('m', True) 
LeafUnit('m', True) 
LeafUnit('m', True) 
True 
True 
False 
IncompatibleUnitsError 

酸洗ユニットは、それらを破った場合、それはその事実がなければ、私は、理解したいですrepr()は同じ結果を返しています。私は何が欠けていますか?

これは、単位パッケージのv0.04を使用して、Google App Engineの1.4 SDK 1

答えて

2

される問題があなたのケースがそうでなければではなく、デよりも示すことからインスタンスがpickableはないという単位ではないようです直列化されたインスタンスは元のインスタンスと等価ではないため、それらは同等であるにもかかわらず互換性のないユニットとして扱われます。

私は前にユニットを使用したことがないが、そのソースをスキミングした後、問題は、両方のインスタンスが等しい比較けどLeafUnitもその塩基が__eq__メソッドを定義units.compatibility.compatibleかどうかをチェックするので、オブジェクトのアイデンティティは(Pythonのセマンティクスごと)の代わりにチェックされているようです。

が同じインスタンス(同じメモリアドレスなど)である場合、2つのユニットインスタンスは等しいだけを比較し、同等のものは2つではありません。通常、シリアル化されたインスタンスをアンピクルした後は、元のインスタンスと同じインスタンスにはなりません(同等、はい、同じではありません)。

解決策は、モンキーパッチユニットです。抽象的な.AbstractUnitは__eq__メソッド:

インスタンスの表現を比較することは最適ではありませんが、ユニットに精通していないことが私が思いつくことができます。著者に、ユニットをより「似ている」ように頼んでください。

+0

興味深いです。明らかに* ideal *ではありませんが、図書館が更新されるまでクライテリアを得ることができます。私はクラスでこれを定義するつもりだと思う。なぜなら私はそれをローカルに組み込むからだ。私は今著者と連絡を取り合い、彼らが何を考えているかを見ていきます。 – woodardj

0

あなたはそのpickleを希望した場合は、あなたのコードと同じインスタンスを作成し、あなたがcopy_reg.dispatch_table__reduce__()実装を登録できます。

import copy_reg 

from units import LeafUnit 

def leafunit_reduce(self): 
    return LeafUnit, (self.specifier, self.is_si()) 

copy_reg.pickle(LeafUnit, leafunit_reduce) 
+0

これは魅力的なオプションですが、ライブラリーではいくつかのタイプが定義されていますが、これは酸漬けになる可能性があり、すべてのクラスでこれを定義する必要があります。 – woodardj

関連する問題