Многопроцессорность не очень хорошо работает с вложенными функциями в некоторых случаях

У меня есть фрагмент кода, хранящийся в строке (пользователь редактирует это в текстовом поле в моем приложении). В этом коде есть функция, которую я хочу запустить позже, используя multiprocess.Pool, Но это не работает, если функции, определенные в строке, являются вложенными.

Обратите внимание, что я использую multiprocessвместо стандартного multiprocessing, который не сможет запускать функции, определенные в строке вообще.

Посмотрите комментарии в следующем фрагменте, чтобы увидеть, что происходит. Есть ли обходной путь, который я мог бы использовать в моем сценарии?

funcs = """
def func(x):
    return func_inner(x) + 1

def func_inner(x):
    return x + 1
"""

import multiprocess

if __name__ == "__main__":
    symbols = dict()
    exec(funcs, symbols)
    func = symbols["func"]
    print(func(1))  # this is evaluated correctly as 3 so nesting functions work fine!
    data = [1, 2, 3]
    pool = multiprocess.Pool()
    print(pool.map(func, data))  # this fails with NameError: name 'func_inner' is not defined!

Я попробовал это на Windows и Linux, а также. мой multiprocess версия 0.70.5 и Python 3.5.

1 ответ

Кажется, ты просто скучаешь compile() для вашей строковой функции:

funcs=compile("""
def func(x):
    return func_inner(x) + 1

def func_inner(x):
    return x + 1
""", '<string>', 'exec')

if __name__ == "__main__":
   import multiprocess

   symbols = dict()
   exec(funcs, symbols)
   func = symbols["func"]
   print(func(1))
   data = [1, 2, 3]
   pool = multiprocess.Pool()
   print(pool.map(func, data))

выходы для меня: [3, 4, 5]

ОБНОВЛЕНИЕ: моя многопроцессорная версия - 0.70.4, попробуйте следующее грязное исправление, должно работать для вас:

import multiprocess

code_globals = {}
code_locals = {}
exec funcs in code_globals, code_locals
print code_locals
# {'func_inner': <function func_inner at 0x10aa607d0>, 'func': <function func at 0x10a97dde8>}

code_globals['func_inner']=code_locals['func_inner']

print code_globals['func_inner']
#<function func_inner at 0x10a1427d0>

func = code_locals['func']
print(func(1))
data = [1, 2, 3]
pool = multiprocess.Pool()
print(pool.map(func, data))
Другие вопросы по тегам