是否有可能腌制Python“单位”?单位?
我正在使用Python“units”包(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() 为它们返回相同的结果,我会理解酸洗单元是否会破坏它们。我缺少什么?
这是使用units包的v0.04和Google App Engine 1.4 SDK 1
I'm using the Python "units" package (http://pypi.python.org/pypi/units/) and I've run into some trouble when trying to pickle them. I've tried to boil it down to the simplest possible to case to try and figure out what's going on. Here's my simple test:
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))
The output I'm seeing when I run this is:
LeafUnit('m', True)
LeafUnit('m', True)
LeafUnit('m', True)
True
True
False
IncompatibleUnitsError
I'd understand if pickling units broke them, if it weren't for the fact that repr() is returning identical results for them. What am I missing?
This is using v0.04 of the units package, and Google App Engine 1.4 SDK 1
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题似乎不在于 Unit 实例不可选择,因为您的情况显示了其他情况,而是反序列化的实例与原始实例不相等,因此它们被视为不兼容的单元,即使它们是等效的。
我以前从未使用过单位,但浏览其源代码后,问题似乎是
units.compatibility.兼容
检查两个实例是否比较相等,但 LeafUnit 及其基数定义了__eq__
方法因此会检查对象的身份(根据 python 的语义)。也就是说,两个单元实例只有在同一个实例(相同的内存地址等)而不是两个相等的实例时才比较相等。通常,在取消序列化实例后,它不会与原始实例相同(等效,是的,但不相同)。
解决方案可能是对units.abstract.AbstractUnit进行猴子补丁以使其具有
__eq__< /code> 方法:
请注意,比较实例的表示并不是最理想的,但不熟悉单位是我能想到的最好的方法。最好要求作者让单元变得更加“比较友好”。
It seems that the problem is not that Unit instances are not pickable since your case shows otherwise but rather than the de-serialized instance does not compare equal to the original instance hence they're treated as incompatible units even though they're equivlent.
I have never used unit before but after skimming its source it seems that the problem is that
units.compatibility.compatible
checks if both instances compare equal but LeafUnit nor its bases define an__eq__
method hence object's identity is checked instead (per python's semantics).That is, two unit instances will only compare equal if they are the same instance (the same memory address, etc), not two equivalent ones. Normally, after you unpickle a serialized instance it will not be the same instance as the original one (equivalent, yes, but not the same)
A solution could be to monkey-patch units.abstract.AbstractUnit to have an
__eq__
method:Note that comparing the instances' representations is suboptimal but not being familiar with unit is the best I can come up with. Better ask the author(s) to make unit more "comparable friendly".
如果您希望
pickle
创建与您的代码相同的实例,那么您可以在copy_reg.dispatch_table
:If you'd like that
pickle
creates the same instances as your code then you could register__reduce__()
implementation incopy_reg.dispatch_table
: