ProcessPoolExecutor не может выполнять мои собственные функции, но выполняет печать

Код:

if __name__ == "__main__": p = ProcessPoolExecutor() p.submit(lambda x: print(x), "something") # doesn't work p.submit(print, "something") # works fine time.sleep(0.5) 

Почему это имеет смысл?

9X_python-shell

4
0
2
Общее количество ответов: 2

Ответ #1

Ответ на вопрос: ProcessPoolExecutor не может выполнять мои собственные функции, но выполняет печать

ProcessPoolExecutor хочет замариновать функцию, но поскольку 9X_py лямбда не имеет имени, ее нельзя найти для 9X_pythonista замаринования.

Например:

from pickle import dumps def fun(x): print(x) lmb = lambda x: print(x) dumps(fun) # succeeds dumps(lmb) # fails 

Итак, это будет работать 9X_python нормально:

import time from concurrent.futures import ThreadPoolExecutor def fun(x): print(x) if __name__ == "__main__": p = ThreadPoolExecutor() lmb = lambda x: print(x) p.submit(lmb, "lambda") # works fine p.submit(fun, "local function") # works fine p.submit(print, "built-in function") # works fine time.sleep(0.5) 

Но если вы замените ThreadPoolExecutor() на ProcessPoolExecutor(), который 9X_pythonic должен будет замариновать функцию, лямбда 9X_python-shell перестанет работать.

from concurrent.futures import ProcessPoolExecutor if __name__ == "__main__": p = ProcessPoolExecutor() lmb = lambda x: print(x) future = p.submit(lmb, "lambda") # doesn't work print(future.result()) 

Это показывает, что 9X_python проблема действительно возникает при травлении, а 9X_pythonic также объясняет, почему:

_pickle.PicklingError: Can't pickle at 0x00000294E66B3E20>: attribute lookup on __main__ failed 

__main__ — это основной 9X_python-shell процесс, в пространстве имен которого нет 9X_python-interpreter лямбды, потому что сама лямбда безымянна. Присвоение 9X_py его переменной типа lmb не меняет этого, поскольку 9X_python-multiprocessing лямбда разыменовывается из переменной. Две 9X_py другие функции по своей сути имеют имена 9X_python-interpreter в пространстве имен __main__ и могут быть замаринованы.

Обратите 9X_python-shell внимание, что __main__ — это то же имя, которое 9X_pythonic вы бы проверили в:

if __name__ == "__main__": 

10
0

Ответ #2

Ответ на вопрос: ProcessPoolExecutor не может выполнять мои собственные функции, но выполняет печать

Если вы проверите result будущего, вы увидите 9X_python-shell соответствующее сообщение об ошибке:

>>> from concurrent.futures import ProcessPoolExecutor >>> p = ProcessPoolExecutor() >>> p.submit(lambda x: print(x), "something").result() ... PicklingError: Can't pickle at 0x113eec5e0>: attribute lookup on __main__ failed 

Таким 9X_python-multiprocessing образом, это сообщение об ошибке говорит 9X_python само за себя, если вы знакомы с тем, как 9X_pythonista работает исполнитель пула процессов. Но 9X_pythonista если это не так, то может потребоваться 9X_python-multiprocessing дополнительное объяснение: процесс попытается 9X_python-multiprocessing получить доступ к рабочей функции по имени, но, поскольку 9X_python лямбда-функции являются "анонимными" функциями, у 9X_python-multiprocessing них нет допустимого имени для поиска в модуле. пространство 9X_py имен.

>>> (lambda x: print(x)).__name__ '' 

В качестве обходного пути вы можете 9X_pythonista использовать многопроцессорный пул pathos, который 9X_python использует dill, более мощную библиотеку сериализации, чем 9X_pythonic pickle. В отличие от pickle, укроп может сериализовать 9X_python-multiprocessing лямбда-выражения. Пафосный интерфейс ProcessPool немного 9X_python-multiprocessing отличается от многопроцессорной обработки 9X_python stdlib ProcessPoolExecutor, но ближайшей аналогией с вашим 9X_pythonista простым использованием submit будет pipe:

>>> from pathos.multiprocessing import ProcessPool >>> p = ProcessPool() >>> p.pipe(lambda x: print(x), "something") something 

Если вам 9X_pythonic интересно, как укроп может сбрасывать лямбды, включите 9X_python-interpreter трассировку и посмотрите, что он на самом 9X_python деле делает с помощью этого фрагмента:

import dill.detect dill.detect.trace(True) dill.dumps(lambda x: print(x)) 

3
0