2016-11-22 3 views
0

Mit multiprocessing auf Methoden erhalten wir Fehler unter Angabe self.methods cannot be pickled.MultiProcessing mit self.methods

dieses Ich zu überwinden verwendet:

def _pickle_method(m): 
    if m.im_self is None: 
     return getattr, (m.im_class, m.im_func.func_name) 
    else: 
     return getattr, (m.im_self, m.im_func.func_name) 


copy_reg.pickle(types.MethodType, _pickle_method) 

Nun suchte ich darüber, aber einige Fragen sind noch unklar:

  1. Warum werden nicht self.methods gebeizt?
  2. Wie funktioniert copy_reg.pickle()? Wie ermöglicht es das Beizen von self.methods?
  3. Gibt es irgendwelche Nachteile bei der Verwendung dieses Ansatzes oder gibt es andere, bessere Methoden?

Mehr Info:

hatte ich eine Funktion in einer Klasse, die ein request.get und request.post zu tun verwendet. Um die Zeiten zu verbessern, habe ich Multiprocessing verwendet. Dies ist das genaue Problem, dem ich gegenüberstand.

SO Question

+0

Ohne weitere Informationen, ist es schwer zu verstehen, _why_ ' pickle' würde versuchen, eine tatsächliche Klassenmethode zu serialisieren (das ist nicht wie 'pickl e' macht Dinge) - so ist es möglich, Antwort ist "Wenn du das tun musst, machst du etwas anderes falsch." Bitte [bearbeiten] Sie Ihre Frage und fügen Sie mehr Kontext hinzu. – martineau

+0

Was genau ist 'self.methods'? Wenn möglich, zeigen Sie die Klasse mit der Methode an, die 'request.get' und' request.post' (und die zugehörige Multiprocessing) ausführt. – martineau

+0

@martineau Ich habe gerade den Namen self.mathods verwendet .... sie sind nur irgendwelche Methoden der Klasse, die sich selbst nehmen ...... der Code kann in der verbundenen SO-Post gefunden werden ... ist gleich oder ähnlich – vks

Antwort

2

Ihre beabsichtigte Verwendung ist noch ein wenig vage-so werde ich stattdessen einen Weg zeigt die linked question in der neuen „Mehr Info“ Ihre Frage zu lösen, die nicht die die byte- Beizen erfordern Code einer Klassenmethode. Ich denke, wie es das macht es ziemlich offensichtlich ist ...

someclass.py

import multiprocessing 

def call_method(x): 
    return SomeClass().f(x) 

class SomeClass(object): 
    def __init__(self): 
     pass 

    def f(self, x): 
     return x*x 

    def go(self): 
     pool = multiprocessing.Pool(processes=4) 
     print pool.map(call_method, range(10)) 

test.py

import someclass 

if __name__== '__main__' : 
    sc = someclass.SomeClass() 
    sc.go() 

Ausgang:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 
+0

' pickle' serialisiert Code nicht. Es speichert genügend Informationen über alle, die gespeichert werden müssen, damit sie bei Bedarf importiert werden können. Die Funktion 'copy_reg()' ist in der [Online-Dokumentation] (https://docs.python.org/2/library/copy_reg.html) beschrieben. Es ist eine Möglichkeit, eine Funktion mit einem bestimmten Datentyp zu verknüpfen (registrieren). Diese Funktion wird aufgerufen, wenn versucht wird, ein Objekt des angegebenen Typs zu serialisieren. – martineau

+0

ohh ok .... die Dinge aufklären ... nur eine Frage bleibt ... warum Multiprocess pickle self.methods kann nicht, während es bei der Verwendung normaler Funktionen kann. Die SO-Link in Frage erklärt, aber können Sie mehr Licht werfen über es.M bin immer noch nicht sicher über diesen Teil. – vks

+0

@vks: Ich bin mir nicht sicher, was du damit meinst mit "normalen Funktionen". Es gibt keine Notwendigkeit, integrierte Funktionen zu putzen, weil sie immer verfügbar sind. – martineau