Python exec() с определением функции в подпроцессеPython

Программы на Python
Гость
Python exec() с определением функции в подпроцессе

Сообщение Гость »


Я запускаю несколько строк с помощью Python exec() последовательно, как в Jupyter Notebook, что означает, что последующие блоки могут получать доступ к переменным, определенным в предыдущих блоках.

Я надеюсь уничтожить его, если определенный блок работает дольше 1 с, поэтому я выполняю его с помощью multiprocess.apply_sync.

Конечно, я поддерживаю local_namespace при вызове exec(), а из-за многопроцессорности я передаю и возвращаю local_namespace с помощью multiprocess.Manager.

Но я обнаружил, что если в моем исполняемом блоке есть определения функций, пространство local_namespace становится None. Все работает нормально, если нет определений функций или если я вызываю exec() в своем основном процессе.

Вот код:

импортировать систему импортировать обратную трассировку импортный маринованный огурец из многопроцессорного импорта Процесс, Пул, Менеджер рабочий рабочий (код, пространство имен): # глобальный код global_namespace = пространство имен['global_namespace'] local_namespace = пространство имен['local_namespace'] пытаться: exec(код, global_namespace, local_namespace) кроме исключения как e: печать (traceback.format_exc()) # Здесь я вижу, что пространство local_name становится None Pickle.dump(local_namespace, open('local_namespace', 'wb')) пространство имен['global_namespace'] = global_namespace пространство имен['local_namespace'] = local_namespace вернуть local_namespace['ans'] Защиту Execute_code (код, пространство имен): рез = Нет print('входной код:\n{}\n*********'.format(код)) пытаться: code_prev_line, code_last_line = кортеж(code.strip().rsplit('\n', maxsplit=1)) кроме: print('исключение:', код) еще: code = '{}\nans = {}'.format(code_prev_line, code_last_line) print('исполняемый код:\n{}\n********'.format(код)) с пулом (процессы = 1) в качестве p: результат = p.apply_async(работник, (код, пространство имен)) пытаться: res = result.get(таймаут=1) кроме: проходить print('выполненный результат:', res) print('local_namespace:', namespace['local_namespace']) вернуть разрешение, пространство имен если __name__ == '__main__': # Этот код приводит к ошибке только в многопроцессорном режиме а = ''' защита f(): х = 1 у = 2 г = х + у вернуть z е() ''' # Этот код отлично работает как в многопроцессорном, так и в основном процессе а = ''' х = 1 у = 2 х + у ''' # основной процесс local_namespace = {} exec(a, None, local_namespace) print('local_namespace:', local_namespace) # многопроцессорность с Manager() в качестве менеджера: пространство имен = { 'global_namespace': {}, 'local_namespace': {} } общее_пространство_имен = менеджер.dict(пространство имен) res, пространство имен =execute_code(a,shared_namespace) # print('local_namespace:', пространство имен) Я пробовал запускать код как в основном процессе, так и в мультипроцессе, а также пробовал код с определениями функций и без них. Только выполнение кода с определением функции в мультипроцессе приводило к ошибке (local_namespace становится None после exec())

Я нашел несколько ответов, предлагающих добавить global f(), и попробовал это. Это сработало. Но я не могу понять причину, поскольку я уже передал {} как global_namespace в exec

Вернуться в «Python»