141 Stimmen

Gibt es eine einfache Möglichkeit, eine Python-Funktion (oder anderweitig serialisieren seinen Code) zu beizen?

Ich versuche, eine Funktion über eine Netzwerkverbindung zu übertragen (mit asyncore). Gibt es eine einfache Möglichkeit, eine Python-Funktion (eine, die, in diesem Fall zumindest, keine Nebenwirkungen haben) für die Übertragung wie diese zu serialisieren?

Im Idealfall hätte ich gerne ein Paar Funktionen, die diesen ähnlich sind:

def transmit(func):
    obj = pickle.dumps(func)
    [send obj across the network]

def receive():
    [receive obj from the network]
    func = pickle.loads(s)
    func()

6voto

am70 Punkte 511

In modernem Python können Sie Funktionen und viele Varianten beizen. Betrachten Sie dies

import pickle, time
def foobar(a,b):
    print("%r %r"%(a,b))

Sie können es einlegen

p = pickle.dumps(foobar)
q = pickle.loads(p)
q(2,3)

Sie können Verschlüsse einlegen

import functools
foobar_closed = functools.partial(foobar,'locked')
p = pickle.dumps(foobar_closed)
q = pickle.loads(p)
q(2)

auch wenn der Abschluss eine lokale Variable verwendet

def closer():
    z = time.time()
    return functools.partial(foobar,z)
p = pickle.dumps(closer())
q = pickle.loads(p)
q(2)

aber wenn Sie es mit einer internen Funktion schließen, wird es fehlschlagen

def builder():
    z = 'internal'
    def mypartial(b):
        return foobar(z,b)
    return mypartial
p = pickle.dumps(builder())
q = pickle.loads(p)
q(2)

mit Fehler

pickle.PicklingError: Kann die <Funktion mypartial bei 0x7f3b6c885a50> nicht beizen: sie wird nicht als __ main __.mypartial gefunden

Getestet mit Python 2.7 und 3.6

5voto

stevegt Punkte 1470

Les cloud Paket (pip install cloud) kann beliebigen Code, einschließlich Abhängigkeiten, picken. Siehe https://stackoverflow.com/a/16891169/1264797 .

3voto

Yanni Papadakis Punkte 127
code\_string = '''
def foo(x):
    return x \* 2
def bar(x):
    return x \*\* 2
'''

obj = pickle.dumps(code\_string)

Jetzt

exec(pickle.loads(obj))

foo(1)
> 2
bar(3)
> 9

3voto

Simon C Punkte 146

Cloudpickle ist wahrscheinlich das, wonach Sie suchen. Cloudpickle wird wie folgt beschrieben:

cloudpickle ist besonders nützlich für Cluster-Computing, wo Python Python-Code über das Netz verschickt wird, um ihn auf entfernten Rechnern auszuführen, möglicherweise in der Nähe der Daten.

Beispiel für die Verwendung:

def add_one(n):
  return n + 1

pickled_function = cloudpickle.dumps(add_one)
pickle.loads(pickled_function)(42)

2voto

Fardin Abdi Punkte 1110

Sie können dies tun:

def fn_generator():
    def fn(x, y):
        return x + y
    return fn

Jetzt, transmit(fn_generator()) sendet die aktuelle Definition von fn(x,y) anstelle eines Verweises auf den Modulnamen.

Sie können den gleichen Trick anwenden, um Klassen über das Netzwerk zu senden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X