是否可以腌制蟒蛇“单位”单位?

时间:2011-01-03 06:47:38

标签: python google-app-engine pickle units-of-measurement

我正在使用Python“单元”软件包(http://pypi.python.org/pypi/units/),并且在尝试腌制它们时遇到了一些麻烦。我试图将其归结为最简单的可能情况,试图弄清楚发生了什么。这是我的简单测试:

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 个答案:

答案 0 :(得分:2)

似乎问题不是单元实例不可拾取,因为你的情况显示不是这样,而是反序列化的实例与原始实例不相等,因此它们被视为不兼容的单元,即使它们是equivlent。

我以前从未使用过单位,但在略读其来源后,似乎问题是units.compatibility.compatible检查两个实例是否相等,但LeafUnit及其基数定义了__eq__方法,因此检查了对象的身份相反(根据python的语义)。

也就是说,如果两个单元实例 相同的实例(相同的内存地址等),而不是两个等效实例,则它们只会相等。通常,在取消对序列化实例的取消后,它将不是与原始实例相同的实例(等效,是,但不相同)

一个解决方案可能是修补单元.abstract.AbstractUnit有一个__eq__方法:

AbstractUnit.__eq__ = lambda self, other: repr(self)==repr(other)

请注意,比较实例的表示是不是最理想的,但不熟悉单位是我能想到的最好的。更好地要求作者使单位更“友好”。

答案 1 :(得分: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)