Pythonにはpickleモジュールというシリアライズ用のモジュールが用意されています。
色んなものをシリアライズ・デシリアライズ可能というスグレモノなんですが、”Pythonに元々用意されている基本的なデータ型のみを利用したデータ”以外のものをシリアライズして、別のプログラムでデシリアライズする際には注意を要します。
>>> import pickle >>> d = dict(a = 'aa', b = 'bb', c = range(3)) >>> pickle.dumps(d) "(dp0\nS'a'\np1\nS'aa'\np2\nsS'c'\np3\n(lp4\nI0\naI1\naI2\nasS'b'\np5\nS'bb'\np6\ns." >>> >>> def f(): ... print 'test' ... >>> pickle.dumps(f) 'c__main__\nf\np0\n.' >>> >>> class c(object): ... def test(self): ... print 'test' ... >>> pickle.dumps(c) 'c__main__\nc\np0\n.' >>>
この対話モードでの結果を見ると分かると思いますが、関数やクラスの定義の内容はシリアライズされません。
つまり基本的に関数やクラスをシリアライズしたプログラムでしかデシリアライズ出来ませんし、別のプログラムで正常にデシリアライズするためにはそちらで全く同じ関数やクラスを定義しておく必要があります。
(シリアライズ・デシリアライズ可能な前提条件を満たすと、シリアライズ・デシリアライズする必要がなくなるという…)
基本的にpickleは別のプログラム間ではデータのやりとりにしか使えない、という事が言えると思います。
では、関数やクラスの定義の内容をシリアライズして別のプログラムでデシリアライズし実行するにはどうすればいいか。
大まかには、定義の文字列化(シリアライズ)、文字列をPythonインタープリタに解釈させる(デシリアライズ)、その結果を利用する(実行)という手順でいけそうです。
とりあえず関数の例をあげると以下のようになります。
シリアライズ元
# getsourcelinesは対話モードでは使えないので注意 from inspect import getsourcelines def f(): print 'test' s = ''.join(getsourcelines(f)[0])
デシリアライズ先
# シリアライズ元の変数sを何らかの方法で受け取った後 code = compile(s, '', 'exec') _locals = {} exec(code, {}, _locals) f = _locals.values()[0] # f()で元の関数を実行可能
ただしこの方法は再帰的なシリアライズは行ってないので、独自に定義したグローバル変数(モジュール、関数、クラス)をシリアライズする関数内で利用してると、デシリアライズ先で実行時にエラーが出るはずです。
デシリアライズ先をサーバプログラム化して、TCPで待ち受けさせて、要求がきたら実行して結果を返す。という風にすると制限はありますがPythonサーバ(CPUサーバ?)みたいなものが比較的簡単に出来るんじゃないかと思います。
さらに共有ストレージを実装し、簡易的なMapReduceな仕組みにすれば、スケールアウトも簡単にできそうです。
というか実はMapReduceのプロトタイプの完成まであと少しで、幾つかの制限を緩和する方法が見つかれば…というところなんですが、すこしモチベーションが下がってきたので、記事を書いてみた次第であります。
最近のコメント
名前
しゅごい
Jane Doe
FYI Avoid Annoying Unexpe…
Jane Doe
ご存じとは思いますが、whileには、”~の間”と…
peta_okechan
針金みたいなパーツを引っ張ると外れます。 他の方の…
虎徹ファン交換
虎徹の標準ファンを外す際に、どのようにして外されま…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…
花粉症対策2019 – 日曜研究室
[…] 花粉症対策についてはこれまで次の記事を書いてきました。https://…