Im Nachgang zu dieser Frage: Is there an easy way to pickle a python function (or otherwise serialize its code)?Wie pickel ich eine Python-Funktion mit ihren Abhängigkeiten?
Ich möchte ein Beispiel für diese Kugel aus dem obigen Beitrag sehen:
„Wenn die Funktion Referenzen Globals (einschließlich importierter Module, anderen Funktionen usw.) Sie müssen diese ebenfalls serialisieren oder auf der Remote-Seite neu erstellen. In meinem Beispiel wird nur der globale Namespace des Remote-Prozesses angegeben. "
Ich habe einen einfachen Test zu gehen, wo ich in eine Datei Marshal mit einem Funktionen-Byte-Code schreibe:
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)
Dann eine neue Python-Instanz starten ich tun:
file = open('/tmp/f2.txt', 'r')
code = marshal.loads(file.read())
func2 = types.FunctionType(code, globals(), "some_func_name");
func2('blah')
Dies führt zu a:
NameError: global name 'g' is not defined
Dies ist unabhängig von den verschiedenen Ansätze, die ich gemacht habe, einschließlich g. Ich habe im Prinzip den gleichen Ansatz versucht, g als f zu senden, aber f kann g immer noch nicht sehen. Wie bekomme ich g in den globalen Namespace, damit er im Empfangsprozess von f verwendet werden kann?
Jemand empfiehlt auch Pyro als ein Beispiel dafür, wie dies zu tun ist. Ich habe bereits versucht, den Code im Discoprojekt zu verstehen. Ich nahm ihre dPickle-Klasse und versuchte, ihre disco/tests/test_pickle.py-Funktionalität in einer eigenständigen App ohne Erfolg neu zu erstellen. Mein Test hatte Probleme beim Marshallen mit dem Dump-Aufruf. Wie auch immer, vielleicht ist eine Pyro Exploration die nächste.
Zusammenfassend ist die Grundfunktionalität, die ich habe, in der Lage, eine Methode über die Leitung zu senden und alle grundlegenden "Arbeitsbereich" Methoden mit sich zu senden (wie g).
Beispiel mit Änderungen von Antwort:
Arbeiten 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)
Arbeiten 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()
Oh wow, ich wusste nicht, dass die zugewiesene Referenz einen Unterschied gemacht hat! Vielen Dank! Wird Arbeitscode posten. –
@RyanR. : Ich habe selbst einen Code veröffentlicht. – kindall
Großartig, ich mag die Sandbox. Sie möchten das nächste automatische Serialisieren aller Funktionenabhängigkeiten automatisch erkunden. So ähnlich wie die disco modutil.find_modules Methode. Schätze die Hilfe. –