Sie können den Funktionsbytecode serialisieren und dann auf dem Aufrufer rekonstruieren. Das Marshall- Modul kann zum Serialisieren von Codeobjekten verwendet werden, die dann wieder zu einer Funktion zusammengesetzt werden können. dh:
import marshal
def foo(x): return x*x
code_string = marshal.dumps(foo.func_code)
Dann im Remote-Prozess (nach der Übertragung von code_string):
import marshal, types
code = marshal.loads(code_string)
func = types.FunctionType(code, globals(), "some_func_name")
func(10) # gives 100
Ein paar Einschränkungen:
Das Marshall-Format (ein beliebiger Python-Bytecode) ist möglicherweise nicht mit den wichtigsten Python-Versionen kompatibel.
Funktioniert nur für die cpython-Implementierung.
Wenn die Funktion auf globale Elemente (einschließlich importierter Module, anderer Funktionen usw.) verweist, die Sie abrufen müssen, müssen Sie diese ebenfalls serialisieren oder auf der Remote-Seite neu erstellen. In meinem Beispiel wird nur der globale Namespace des Remote-Prozesses angegeben.
Sie müssen wahrscheinlich etwas mehr tun, um komplexere Fälle wie Schließungen oder Generatorfunktionen zu unterstützen.
marshal
Modul anzuwenden, um ein Wörterbuch von Wörterbüchern zu serialisieren, das als initialisiert wurdedefaultdict(lambda : defaultdict(int))
. Aber es gibt den Fehler zurückValueError: unmarshallable object
. Hinweis: Ich verwende Python2.7. Irgendeine Idee? Dankefoo.func_code
wirftAttributeError
. Gibt es eine andere Möglichkeit, den Funktionscode abzurufen?Schauen Sie sich Dill an , das die Pickle-Bibliothek von Python erweitert, um eine größere Vielfalt von Typen zu unterstützen, einschließlich Funktionen:
Es werden auch Verweise auf Objekte beim Schließen der Funktion unterstützt:
quelle
Pyro kann das für Sie tun .
quelle
Der einfachste Weg ist wahrscheinlich
inspect.getsource(object)
(siehe das Inspect-Modul ), einen String mit dem Quellcode für eine Funktion oder eine Methode zurückzugeben.quelle
Es hängt alles davon ab, ob Sie die Funktion zur Laufzeit generieren oder nicht:
Wenn Sie dies tun
inspect.getsource(object)
, funktioniert dies nicht für dynamisch generierte Funktionen, da die Quelle des Objekts aus der.py
Datei abgerufen wird. Daher können nur Funktionen, die vor der Ausführung definiert wurden, als Quelle abgerufen werden.Und wenn Ihre Funktionen ohnehin in Dateien abgelegt sind, können Sie dem Empfänger Zugriff darauf gewähren und nur Modul- und Funktionsnamen weitergeben.
Die einzige Lösung für dynamisch erstellte Funktionen, die ich mir vorstellen kann, besteht darin, die Funktion vor der Übertragung als Zeichenfolge zu konstruieren, die Quelle zu senden und dann
eval()
auf der Empfängerseite.Bearbeiten: Die
marshal
Lösung sieht auch ziemlich schlau aus, wusste nicht, dass Sie etwas anderes als eingebaute serialisieren könnenquelle
Das
cloud
Paket (pip install cloud) kann beliebigen Code einschließlich Abhängigkeiten auswählen. Siehe https://stackoverflow.com/a/16891169/1264797 .quelle
Jetzt
quelle
Du kannst das:
Jetzt
transmit(fn_generator())
wirdfn(x,y)
anstelle eines Verweises auf den Modulnamen die eigentliche Definition von gesendet .Mit demselben Trick können Sie Klassen über das Netzwerk senden.
quelle
Die für dieses Modul verwendeten Grundfunktionen decken Ihre Abfrage ab, und Sie erhalten die beste Komprimierung über das Kabel. Siehe den lehrreichen Quellcode:
y_serial.py module :: warehouse Python-Objekte mit SQLite
"Serialisierung + Persistenz :: Komprimieren und kommentieren Sie Python-Objekte in wenigen Codezeilen in SQLite und rufen Sie sie später chronologisch nach Schlüsselwörtern ohne SQL ab. Das nützlichste" Standard "-Modul für eine Datenbank zum Speichern schemaloser Daten."
http://yserial.sourceforge.net
quelle
Cloudpickle ist wahrscheinlich das, wonach Sie suchen. Cloudpickle wird wie folgt beschrieben:
Anwendungsbeispiel:
quelle
Hier ist eine Hilfsklasse, mit der Sie Funktionen umbrechen können, um sie auswählbar zu machen. Die bereits erwähnten Vorsichtsmaßnahmen
marshal
gelten, es wird jedoch versucht, nach Möglichkeit Gurke zu verwenden. Es werden keine Anstrengungen unternommen, um Globale oder Verschlüsse während der Serialisierung zu erhalten.quelle