2016-10-12 3 views
0

私は、次のような単純なクラス定義があります:クラスAPMSimは唯一の例外は、マルチプロセッシング・マネージャーである静的メンバ、ある無地シンプルなPythonのプリミティブ型(文字列、リストなど)によって、純粋に定義されてPython picklingライブラリが存在しないクラスメンバについてなぜ文句を言うのですか?

def apmSimUp(i): 
    return APMSim(i) 

def simDown(sim): 
    sim.close() 

class APMSimFixture(TestCase): 

    def setUp(self): 
     self.pool = multiprocessing.Pool() 
     self.sims = self.pool.map(
      apmSimUp, 
      range(numCores) 
     ) 

    def tearDown(self): 
     self.pool.map(
      simDown, 
      self.sims 
     ) 

を。リストしかし

、私はこのクラスを実行しようとすると、私は次のエラー情報だ:

Error 
Traceback (most recent call last): 
    File "/home/peng/git/datapassport/spookystuff/mav/pyspookystuff_test/mav/__init__.py", line 77, in setUp 
    range(numCores) 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 251, in map 
    return self.map_async(func, iterable, chunksize).get() 
    File "/usr/lib/python2.7/multiprocessing/pool.py", line 567, in get 
    raise self._value 
MaybeEncodingError: Error sending result: '[<pyspookystuff.mav.sim.APMSim object at 0x7f643c4ca8d0>]'. Reason: 'TypeError("can't pickle thread.lock objects",)' 

thread.lockがどこにも見つからないように奇妙である、私は厳密にどのmultithreadiを避けます表示されているように、マルチプロセッシングコンポーネントのみが使用されます。そして、これらのコンポーネントのどれもが私のクラスに存在しないか、静的メンバーとしてしか存在しません。このクラスをpicklableにするにはどうすればよいですか?

ところで、黒いヒツジのメンバーを酸洗いから除外する方法はありますか? Javaの@transientアノテーションと同様?

ありがとうございました!

UPDATE:あなたはそれをpicklabilityに違反する何かを見つけた場合、次は私の完全なAPMSimクラスでは、以下を参照してください。

怠惰なデコレータは、このライブラリーからである

usedINums = mav.manager.list() 
class APMSim(object): 
    global usedINums 

    @staticmethod 
    def nextINum(): 
     port = mav.nextUnused(usedINums, range(0, 254)) 
     return port 

    def __init__(self, iNum): 
     # type: (int) -> None 

     self.iNum = iNum 
     self.args = sitl_args + ['-I' + str(iNum)] 

    @staticmethod 
    def create(): 
     index = APMSim.nextINum() 
     try: 
      result = APMSim(index) 
      return result 
     except Exception as ee: 
      usedINums.remove(index) 
      raise 

    @lazy 
    def _sitl(self): 
     sitl = SITL() 
     sitl.download('copter', '3.3') 
     sitl.launch(self.args, await_ready=True, restart=True) 
     print("launching .... ", sitl.p.pid) 
     return sitl 

    @lazy 
    def sitl(self): 
     self.setParamAndRelaunch('SYSID_THISMAV', self.iNum + 1) 
     return self._sitl 

    def _getConnStr(self): 
     return tcp_master(self.iNum) 

    @lazy 
    def connStr(self): 
     self.sitl 
     return self._getConnStr() 

    def setParamAndRelaunch(self, key, value): 

     wd = self._sitl.wd 
     print("relaunching .... ", self._sitl.p.pid) 
     v = connect(self._getConnStr(), wait_ready=True) # if use connStr will trigger cyclic invocation 
     v.parameters.set(key, value, wait_ready=True) 
     v.close() 
     self._sitl.stop() 
     self._sitl.launch(self.args, await_ready=True, restart=True, wd=wd, use_saved_data=True) 
     v = connect(self._getConnStr(), wait_ready=True) 
     # This fn actually rate limits itself to every 2s. 
     # Just retry with persistence to get our first param stream. 
     v._master.param_fetch_all() 
     v.wait_ready() 
     actualValue = v._params_map[key] 
     assert actualValue == value 
     v.close() 

    def close(self): 

     self._sitl.stop() 
     usedINums.remove(self.iNum) 

https://docs.python.org/2/tutorial/classes.html#generator-expressions

答えて

0

あなたのクラスがどのように見えるかは分かりますが、multiprocessingのメソッドがある場合は、デフォルトでそれを削除するだけの問題があるかもしれません。マルチプロセッシング・オブジェクトはロックを使用することもできますが、これらは(明らかに)unpickle対応です。

__getstate__メソッドまたは__reduce__(同じ場所に記載されています)で酸洗をカスタマイズできます。

+0

しかし、それは静的メンバーです、静的メンバーはトップレベル変数と同じように扱われるはずですか? – tribbloid

+0

既にマルチプロセッシング・マネージャー・リストをグローバル・メンバーに移動しましたが、問題は残ります。私の更新を見てください。 – tribbloid

+0

@tribbloid:いいえ、それを避けるのは簡単ではありません。あなたのためにGoogleの場合は既に議論がかなりあります。なぜピクルにしたいクラスを見せてもらえないのですか? –

関連する問題