Python multiprocessing PicklingError: Can ' T pickle <type 'function'>
Tut mir Leid, dass ich den Fehler reproduzieren können mit einem einfacheren Beispiel, und mein code ist zu kompliziert, zu veröffentlichen. Wenn ich das Programm in der IPython-shell anstelle der regulären Python, alles klappt gut.
Ich sah einige der vorherigen Hinweise auf dieses problem. Sie waren alle durch die Verwendung von pool aufrufen, Funktion innerhalb einer Klasse definiert die Funktion. Aber dies ist nicht der Fall für mich.
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 552, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 505, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 313, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Ich würde jede Hilfe zu schätzen wissen.
Update: Die Funktion habe ich Gurke ist definiert, auf der obersten Ebene des Moduls. Wenn es eine Funktion aufgerufen, die enthält eine geschachtelte Funktion. ich.e f()
Anrufe g()
Anrufe h()
hat eine verschachtelte Funktion i()
, und ich rufe pool.apply_async(f)
. f()
, g()
, h()
sind alle definiert, auf der obersten Ebene. Ich habe versucht, einfacheres Beispiel mit diesem Muster und es funktioniert obwohl.
- Die top-level - / akzeptierte Antwort ist gut, aber es könnte bedeuten, dass Sie brauchen, um neu zu strukturieren Ihres Codes, das könnte schmerzhaft sein. Ich würde empfehlen, für jeden, der dieser Ausgabe Lesen Sie auch die weiteren Antworten Nutzung
dill
undpathos
. Allerdings habe ich kein Glück mit irgendeiner der Lösungen beim arbeiten mit vtkobjects 🙁 Jemand hat es geschafft, führen Sie python-code in Parallelverarbeitung vtkPolyData?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Hier ist ein Liste von dem, was sein kann, gebeizt. Insbesondere sind die Funktionen nur picklable, wenn Sie definiert, auf der obersten Ebene eines Moduls.
Dieses Stück code:
ergibt einen Fehler fast identisch zu dem, das Sie geschrieben:
Das problem ist, dass die
pool
Methoden verwenden alle einenmp.SimpleQueue
übergeben Aufgaben an die worker-Prozesse. Alles das geht über diemp.SimpleQueue
muss aufsammelbare, undfoo.work
ist nicht picklable, denn es ist nicht definiert, auf der obersten Ebene des Moduls.Es kann behoben werden, indem Sie eine Funktion definieren, auf der obersten Ebene, die Anrufe
foo.work()
:Beachten Sie, dass
foo
ist aufsammelbare, daFoo
definiert, auf der obersten Ebene undfoo.__dict__
ist picklable.pool = Pool()
line hier). Ich hatte das nicht erwartet, und dies könnte der Grund sein, warum die OP das problem bestehen.functool.partial
zu einer top-level-Funktion ist auch Gurke-in der Lage, auch wenn es innerhalb einer anderen Funktion definiert.Ich würde verwenden
pathos.multiprocesssing
stattmultiprocessing
.pathos.multiprocessing
ist ein fork vonmultiprocessing
verwendetdill
.dill
serialisieren können fast alles in python, so dass Sie in der Lage sind, zu senden eine Menge mehr rund um parallel. Diepathos
Gabel hat auch die Fähigkeit, arbeiten direkt mit mehreren argument-Funktionen, wie Sie benötigen für die Klasse Methoden.Bekommen
pathos
(und wenn Sie möchten,dill
) hier:https://github.com/uqfoundation
sudo pip install git+https://github.com/uqfoundation/dill.git@master
undsudo pip install git+https://github.com/uqfoundation/pathos.git@master
sudo
(aus externen Quellen wie github vor allem). Stattdessen würde ich empfehlen, um zu laufen:pip install --user git+...
pip install pathos
funktioniert nicht leider und gibt diese Meldung:Could not find a version that satisfies the requirement pp==1.5.7-pathos (from pathos)
multiprocess
die 2/3-kompatibel. Siehe stackoverflow.com/questions/27873093/... und pypi.python.org/pypi/multiprocess.pip install pathos
funktioniert jetzt, undpathos
ist python 3 kompatibel.PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
kann auch passieren, mitpathos/dill
wenn Sie aus irgendeinem Grund gezwungen ist, zu fallen, wieder in den standard -multiprocess/pickle
(siehe github.com/uqfoundation/pathos/issues/67)Wie schon andere gesagt haben
multiprocessing
können nur übertragen Python-Objekte von Arbeitsprozessen, die können werden gebeizt. Wenn Sie nicht organisieren Sie Ihre code, wie beschrieben, durch unutbu, die Sie verwenden könnendill
s extended Beizen/unpickling-Funktionen für die übertragung der Daten (insbesondere die code-Daten), wie ich unten zeigen.Diese Lösung erfordert nur die installation von
dill
und keine anderen Bibliotheken alspathos
:dill
undpathos
Autor... und wenn Sie Recht haben, ist es nicht so viel schöner und sauberer und flexibler, auchpathos
wie in meiner Antwort? Oder vielleicht bin ich ein wenig voreingenommen...pathos
an der Zeit zu schreiben und wollte eine Lösung, die sehr nahe an der Antwort. Nun habe ich gesehen, Ihre Lösung, ich bin damit einverstanden, dass dies der Weg zu gehen.Doh… I didn't even think of doing it like that.
So, dass war irgendwie cool.for
Schleife. Ich würde normalerweise parallel routine nehmen Sie eine Liste und gibt eine Liste ohne Schleife.apply_async
zu Gunsten vonmap_async
, die Strategie zu verwendendill
für das marinieren ist das gleiche.dill
erweitert Gurke Fähigkeiten im Vergleich zupickle
einige Objekte können nicht gebeizt überhaupt, wie z.B. Datei-handles. One-Lösungen ist die Implementierung__setstate__
und__getstate__
Methode pickle / unpickle die notwendigen Daten Attribute. Siehe auch stackoverflow.com/questions/1939058 und docs.python.org/3/library/pickle.html#handling-stateful-objectsIch habe festgestellt, dass ich auch zu generieren, die genau die Fehler-Ausgabe auf ein perfekt funktionierendes Stück code, indem Sie versuchen, verwenden Sie die profiler drauf.
Hinweis, dass dies unter Windows (wo der Gabelung ist ein bisschen weniger elegant).
War ich laufen:
Und gefunden, dass das entfernen des profiling entfernt, die Fehler und die Platzierung der Profilierung restauriert. War treibt mich batty zu, weil ich wusste, dass der code, der verwendet wird, um zu arbeiten. Ich überprüfte, um zu sehen, ob etwas aktualisiert hatte pool.py... dann hatte ein flaues Gefühl und beseitigt die Profilerstellung und das war es.
Posting hier für das Archiv, falls jemand anderes fährt.
Funktioniert es auch für numpy-arrays.
Dieser Fehler wird auch kommen wenn Sie irgendeine eingebaute Funktion im Modell-Objekt, das übergeben wurde, um die async-Jobs.
So stellen Sie sicher, überprüfen Sie die model-Objekte, die übergeben werden nicht haben eingebaute Funktionen. (In unserem Fall waren wir mit
FieldTracker()
Funktion django-Modell-utils innerhalb des Modells zu verfolgen, einen bestimmten Bereich). Hier ist die link zu relevanten GitHub Problem.Gebäude auf @rocksportrocker Lösung,
Würde es Sinn machen, dill beim senden und RECVing die Ergebnisse.