Многопроцессорность в консоли IPython на компьютере с Windows - если требуется __name_
Я работаю с IPython и Spyder IDE на компьютере с Windows. Когда IDE запускается, загружается набор py-файлов для определения некоторых функций, которые немного облегчают мою работу. Все работает как положено.
Теперь я хотел бы обновить одну из этих функций, чтобы использовать многопроцессорность, но в Windows это требует if __name__ == "__main__":
заявление. Поэтому кажется, что я не могу вызвать функцию напрямую и передать аргументы из консоли IPython.
Например, один из py-файлов (назовем его test.py) может выглядеть следующим образом.
import multiprocessing as mp
import random
import string
# define a example function
def rand_string(length, output):
""" Generates a random string of numbers, lower- and uppercase chars. """
rand_str = ''.join(random.choice(
string.ascii_lowercase
+ string.ascii_uppercase
+ string.digits)
for i in range(length))
output.put(rand_str)
def myFunction():
# Define an output queue
output = mp.Queue()
# Setup a list of processes that we want to run
processes = [mp.Process(target=rand_string, args=(5, output)) for x in range(4)]
# Run processes
for p in processes:
p.start()
# Exit the completed processes
for p in processes:
p.join()
# Get process results from the output queue
results = [output.get() for p in processes]
print(results)
В моей консоли IPython я хотел бы использовать строку
myFunction()
запустить все расчеты. Но в Windows в конечном итоге появляется ошибка BrokenPipe.
Когда я положил
if __name__ == "__main__":
myFunction()
в конце py-файла и запустите полный файл
runfile(test.py)
оно работает. Конечно. Но это очень затрудняет передачу аргументов в функцию, так как мне всегда приходится редактировать сам файл test.py.
Мой вопрос: как мне запустить многопроцессорную функцию, не вставляя ее в это if __name__ == "__main__":
заявление??
2 ответа
Итак, я решил эту конкретную проблему.
- Поместите определение
rand_string
в отдельном файле, называемомtest2
, Импортировать
test2
как модуль в мойtest.py
скриптimport test2 as test2
измените следующую строку для доступа к
test2
модульprocesses = [mp.Process(target=test2.rand_string, args=(5, output)) for x in range(4)]
Бежать
test.py
Вызов
myFunction()
Будь счастлив:)
Решение основано на этом многопроцессорном руководстве, в котором предлагается импортировать целевую функцию из другого скрипта. Это решение обходит безопасный самовывоз if __name__
-раппер, чтобы получить доступ к целевой функции.
multiprocessing
не работает без работы с if __name__ == '__main__'
,
Вы могли бы, однако, использовать вилку multiprocessing
что по существу использует dill
рассматривать сеанс переводчика как файл... (короче говоря, он работает).
Python 2.7.9 (default, Dec 11 2014, 01:21:43)
Type "copyright", "credits" or "license" for more information.
IPython 3.0.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: from pathos.multiprocessing import ProcessingPool as Pool
In [2]: def squared(x):
...: return x**2
...:
In [3]: x = range(10)
In [4]: p = Pool()
In [5]: p.map(squared, x)
Out[5]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
In [6]: res = p.imap(squared, x)
In [7]: list(res)
Out[7]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
In [8]:
Вы можете использовать встроенный multiprocessing
это было дополнено dill
Сериализатор тоже, или вы можете построить Queue
с Pool().apipe
или что-то похожее на то, что вам, похоже, интересно Queue
,
Получить пафос здесь: https://github.com/uqfoundation