python pintモジュールは物理量を実装します。マルチプロセッシングと一緒に使用したいと思います。しかし、新しいプロセスでUnitRegistryを作成する方法を知りません。私は直感的な操作を行う場合:私は、引数をunpickle化する前に子プロセスにUnitRegistryの初期化の欠如に由来すると仮定マルチプロセッシングを使用したPython pintモジュール
Traceback (most recent call last):
File "C:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\multiprocessing\process.py", line 254, in _bootstrap
self.run()
File "C:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\pmaunz\PyCharmProjects\IonControl34\tests\pintmultiprocessing.py", line 12, in f
print(one/two)
File "C:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\site-packages\pint\quantity.py", line 738, in __truediv__
return self._mul_div(other, operator.truediv)
File "C:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\site-packages\pint\quantity.py", line 675, in _mul_div
offset_units_self = self._get_non_multiplicative_units()
File "C:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\site-packages\pint\quantity.py", line 1312, in _get_non_multiplicative_units
offset_units = [unit for unit in self._units.keys()
File "C:\WinPython-64bit-3.4.4.2Qt5\python-3.4.4.amd64\lib\site-packages\pint\quantity.py", line 1313, in <listcomp>
if not self._REGISTRY._units[unit].is_multiplicative]
KeyError: 'millisecond'
:
from multiprocessing import Process
from pint import UnitRegistry, set_application_registry
ureg = UnitRegistry()
set_application_registry(ureg)
Q = ureg.Quantity
def f(one, two):
print(one/two)
if __name__ == '__main__':
p = Process(target=f, args=(Q(50, 'ms'), Q(50, 'ns')))
p.start()
p.join()
は、それから私は、次の例外を取得します。 (関数fのUnitRegistryの初期化は、変数が既にunpickleされているので機能しません)。
子プロセスにQuantityを送信するにはどうすればいいですか?ティムピーターの答えの後
編集:
問題はマルチプロセッシングに縛らないです。同じ例外で
from pint import UnitRegistry, set_application_registry
import pickle
ureg = UnitRegistry()
set_application_registry(ureg)
Q = ureg.Quantity
with open("pint.pkl", 'rb') as f:
t1 = pickle.load(f)
t2 = pickle.load(f)
print(t1/t2)
結果:単に新しいスクリプトにunpickle化すると、同じ問題につながり、その後
from pint import UnitRegistry, set_application_registry
import pickle
ureg = UnitRegistry()
set_application_registry(ureg)
Q = ureg.Quantity
with open("pint.pkl", 'wb') as f:
pickle.dump(Q(50, 'ms'), f)
pickle.dump(Q(50, 'ns'), f)
量を酸洗して。 Timが指摘しているように、アンピクルの前にQ(50, 'ns'); Q(50, 'ms')
行を追加すれば十分です。パイントのソースコードを掘り下げると、ユニットms
で数量を作成すると、このユニットは内部レジストリに追加されます。 picklingはUnitContainer
インスタンスを使用してユニットを保存します。番号を付けないで数量を作成すると、はがレジストリに追加されます。
(パイントソースコードで)単純な修正は、文字列を返すように機能Quantity.__reduce__
を変更することです。
diff --git a/pint/quantity.py b/pint/quantity.py
index 3f30a25..695866a 100644
--- a/pint/quantity.py
+++ b/pint/quantity.py
@@ -57,7 +57,7 @@ class _Quantity(SharedRegistryObject):
def __reduce__(self):
from . import _build_quantity
- return _build_quantity, (self.magnitude, self._units)
+ return _build_quantity, (self.magnitude, str(self._units))
def __new__(cls, value, units=None):
if units is None:
私はpintのgithubサイトで問題をオープンしました。
ブラボー!それはすべて理にかなっています。私は驚くことに、誰もこれにぶつかりませんでした。一つのプロセスで漬け込み、別のプロセスではunpickleは、(マルチプロセッシングがない場合でも)漬け物が使われています! –