2014-09-22 14 views
16

otrzymuję ten błąd przy użyciu pool.map(funct, iterable):Python Multiprocessing Lib Error (AttributeError: __exit__)

AttributeError: __exit__ 

bez wyjaśnienia, tylko ślad stosu do pliku pool.py wewnątrz modułu.

korzystając w ten sposób:

with Pool(processes=2) as pool: 
    pool.map(myFunction, mylist) 
    pool.map(myfunction2, mylist2) 

Podejrzewam, że może być problem z picklability (python do pickle potrzeby lub przekształcić dane listy do strumienia bajtów) ale nie jestem pewien, czy to prawda lub jeśli jest to jak debugować.

EDIT: nowy format kodu, który produkuje ten błąd:

def governingFunct(list): 
    #some tasks 
    def myFunction(): 
     # function contents 
    with closing(Pool(processes=2)) as pool: 
     pool.map(myFunction, sublist) 
     pool.map(myFunction2, sublist2) 

ERROR PRODUKCJA:

PicklingError: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed 
+0

co masz na myśli przez 'podczas .. as'? miałeś na myśli 'z'? – Elisha

+0

Do uwzględnienia * pełnego śledzenia * dla błędów i rzeczywistego kodu. 'while' jest oczywistym błędem składni tutaj, na przykład, ale z wyjątku jest jasne, że użyłeś' with' naprawdę. –

Odpowiedz

31

w Pythonie 2.x oraz 3.0, 3.1 i 3.2, multiprocessing.Pool() obiekty są nie menedżerowie kontekst. Nie można ich używać w oświadczeniu with. Tylko w Pythonie 3.3 lub nowszym możesz ich używać jako takich. Od Python 3 multiprocessing.Pool() documentation:

New in version 3.3: Pool objects now support the context management protocol – see Context Manager Types. __enter__() returns the pool object, and __exit__() calls terminate().

We wcześniejszych wersjach Pythona, można użyć contextlib.closing(), ale brać pod uwagę to zadzwoni pool.close(), nie pool.terminate(). Terminate ręcznie w tym przypadku:

from contextlib import closing 

with closing(Pool(processes=2)) as pool: 
    pool.map(myFunction, mylist) 
    pool.map(myfunction2, mylist2) 
    pool.terminate() 

lub stworzyć swój własny menedżer terminating() kontekstowego:

from contextlib import contextmanager 

@contextmanager 
def terminating(thing): 
    try: 
     yield thing 
    finally: 
     thing.terminate() 

with terminating(Pool(processes=2)) as pool: 
    pool.map(myFunction, mylist) 
    pool.map(myfunction2, mylist2) 
+1

Cóż Sir, dziękuję za tak szczegółowe wyjaśnienie. Twoje rozwiązanie spowodowało przesunięcie funkcji o krok bliżej do pracy - teraz otrzymuję ten błąd: 'PicklingError: Can not pickle : wyszukiwanie atrybutów __builtin __. Function failed' – sidewaiise

+0

@sidewaiise: are you próbując użyć metody na lekcji? Zobacz [Przetwarzanie wielostanowiskowe: użycie Pool.map na funkcji zdefiniowanej w klasie] (http://stackoverflow.com/q/3288595) –

+0

Heh Właściwie to przeczytałem to, kiedy to opublikowałeś. Dzięki - niedługo przeczytam i skomentuję. – sidewaiise

1

with stwierdzenie jest dla obiektów, które mają __enter__ i __exit__ funkcje, tj Context Manager Types
multiprocessing.Pool jest nie jest to typ Menedżera kontekstu. spróbuj wykonać następujące czynności:

pool = Pool(processes=2) 
pool.map(myFunction, mylist) 
pool.map(myfunction2, mylist2) 
+0

Pytanie brzmi: * dlaczego OP uważał, że to *. Odpowiedź brzmi, że dokumentacja Pythona 3 mówi, że tak. Ale kwalifikuje się również jako Python 3.3 i wyżej. –

+0

ok. nie wiedziałem, że to kontekstowy mgr w Pythonie 3.3 i wyżej – Elisha

Powiązane problemy