Использование общего пространства имён 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 шт):
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() там больше нет.