многопроцессорная обработка: переменная, на которую ссылаются перед назначением в некоторых случаях, но не в других


Где-то на этом сайте я нашел следующий пример:

import multiprocessing
import ctypes
import numpy as np

shared_array_base = multiprocessing.Array(ctypes.c_double, 10*10)
shared_array = np.ctypeslib.as_array(shared_array_base.get_obj())
shared_array = shared_array.reshape(10, 10)

# No copy was made
assert shared_array.base.base is shared_array_base.get_obj()

# Parallel processing
def my_func(i, def_param=shared_array):
    shared_array[i,:] = i

if __name__ == '__main__':
    pool = multiprocessing.Pool(processes=4)
    pool.map(my_func, range(10))

    print shared_array

Приведенный выше код работает нормально, но если я хочу добавить массив к общему массиву, что-то вроде shared_array += some_other_array (вместо вышеупомянутого shared_array[i,;] = i) я получаю

Локальная переменная 'shared_array', на которую ссылаются перед присвоением

Любые идеи, почему я не могу сделать этого?

1   3   2012-07-12 02:29:27

1 ответ:

Если переменная назначается в любом месте функции, она рассматривается как локальная переменная. shared_array += some_other_array эквивалентно shared_array = shared_array + some_other_array. Таким образом, shared_array рассматривается как локальная переменная, которая не существует в то время, когда вы пытаетесь использовать ее в правой части присваивания.

Если вы хотите использовать глобальную переменную shared_array, вам нужно явно пометить ее как глобальную, поместив global shared_array в свою функцию.

Причина, по которой вы не видите ошибку с shared_array[i,:] = i, заключается в том, что это не присваивает переменная shared_array. Скорее, он мутирует этот объект, присваивая его фрагменту. В Python присвоение голого имени (например, shared_array = ...) очень отличается от любого другого вида присвоения (например, shared_array[...] = ...), даже если они выглядят похожими.

Заметьте, кстати, что эта ошибка не имеет ничего общего с многопроцессорной обработкой.