この質問のフォローアップとして: Python関数をピクルスにする(またはコードをシリアル化する)簡単な方法はありますか?
上記の投稿からこの弾丸の例を見たいと思います:
「関数が取得する必要のあるグローバル(インポートされたモジュール、他の関数などを含む)を参照している場合は、これらもシリアル化するか、リモート側で再作成する必要があります。私の例では、リモートプロセスのグローバル名前空間を示しています。 「」
マーシャルを使用して関数のバイトコードをファイルに書き込む簡単なテストがあります。
def g(self,blah):
print blah
def f(self):
for i in range(1,5):
print 'some function f'
g('some string used by g')
data = marshal.dumps(f.func_code)
file = open('/tmp/f2.txt', 'w')
file.write(data)
次に、新しいpythonインスタンスを開始します。
file = open('/tmp/f2.txt', 'r')
code = marshal.loads(file.read())
func2 = types.FunctionType(code, globals(), "some_func_name");
func2('blah')
これにより、次のようになります。
NameError: global name 'g' is not defined
これは、gを含めるために私が行ったさまざまなアプローチとは無関係です。基本的にgをfと同じ方法で送信しようとしましたが、fはまだgを認識できません。gをグローバル名前空間に入れて、受信プロセスでfが使用できるようにするにはどうすればよいですか?
誰かがこれを行う方法の例としてpyroを見ることも勧めました。私はすでにディスコプロジェクトの関連コードを理解しようと試みました。私は彼らのdPickleクラスを受講し、スタンドアロンアプリでdisco / tests/test_pickle.py機能を再現しようとしましたが成功しませんでした。私の実験では、dumps呼び出しを使用して関数マーシャリングを実行する際に問題が発生しました。とにかく、次はパイロ探査かもしれません。
要約すると、私が求めている基本的な機能は、メソッドをネットワーク経由で送信し、すべての基本的な「ワークスペース」メソッドを送信できるようにすることです(gなど)。
回答からの変更の例:
動作中のfunction_writer:
import marshal, types
def g(blah):
print blah
def f():
for i in range(1,5):
print 'some function f'
g('blah string used by g')
f_data = marshal.dumps(f.func_code)
g_data = marshal.dumps(g.func_code);
f_file = open('/tmp/f.txt', 'w')
f_file.write(f_data)
g_file = open('/tmp/g.txt', 'w')
g_file.write(g_data)
動作中のfunction_reader:
import marshal, types
f_file = open('/tmp/f.txt', 'r')
g_file = open('/tmp/g.txt', 'r')
f_code = marshal.loads(f_file.read())
g_code = marshal.loads(g_file.read())
f = types.FunctionType(f_code, globals(), 'f');
g = types.FunctionType(g_code, globals(), 'g');
f()