Использование общего пространства имён Manager - не присваивается список

Не могу изменить вложенный список (=матрицу двумерную) в общем пространстве имён Manager, находясь в процессе (соответственно, и в main информация не попадает). А именно: в примере ниже ns.my_list[1] не принимает значение списка t (я упростил проблему до минимума при отладке, чтобы сюда всё не помещать). При этом видно в отладочной печати, что ns.my_list[1] – точно список, т.е. по логике, он должен бы принимать значение списка t. О proxy-objects на python.readthedocs.io внимательно почитал, но не увидел ничего об этом. Просьба подсказать, в чем причина.

from multiprocessing import Process, Manager

def process_work(ns):
    t = [1,2,3,4]
    ns.my_list[1]=t
    print ('type of ns.my_list[1]:', type(ns.my_list[1])) # <class 'list'>
    print('ns.my_list[1]', ns.my_list[1])                 #ns.my_list[1] [0, 0, 0, 0]

if __name__ == '__main__':
    mgr=Manager()
    namespace=mgr.Namespace()
    namespace.my_list=mgr.list()
    namespace.my_list= [[0] * 4] * 3 # матрица 3(l)х4(n)

    new_process = Process(target=process_work, args=(namespace,))
    new_process.start()
    new_process.join()

(С простым списком - одномерной матрицей всё работает, через Array тоже всё работает, но хочу иметь возможность многомерные массивы/списки списков возвращать, где каждая строка обрабатывается отдельным процессом. Можно одномерный массив для этого использовать через Array, но не хочу так ограничивать - однажды урезанного знания не хватит).


Ответы (1 шт):

Автор решения: CrazyElf
    namespace.my_list = mgr.list()
    namespace.my_list = [[0] * 4] * 3 # матрица 3(l)х4(n)

Так вы заменили mgr.list() в поле namespace.my_list обычным списком, поэтому ничего и не работает. Нужно использовать mgr.list() и тогда всё работает:

    namespace.my_list = mgr.list([[0] * 4] * 3) # матрица 3(l)х4(n)

Вывод:

type of ns.my_list[1]: <class 'list'>
ns.my_list[1] [1, 2, 3, 4]

Либо, если вы хотите заполнять этот список постепенно, то делать так:

    namespace.my_list = mgr.list()
    for _ in range(3):
        namespace.my_list.append([0] * 4)

Но в любом случае основное тут - чтобы в namespace.my_list был обязательно mgr.list(). А когда вы присваиваете в namespace.my_list результат работы спискового включения, то вы заменяете эту переменную и mgr.list() там больше нет.

→ Ссылка