Не удается вернуть manager.list в Python многопроцессорная обработка из подпроцесса происходит из array.tolist () - PullRequest
0 голосов
/ 07 марта 2020

Я хотел бы изменить manager.list в многопроцессорном подпроцессе с помощью array (a) .tolist (). Добавление списка в подпроцесс работает, но изменение с помощью этого метода не работает.

Любой намек, что не так? Большое спасибо.

from multiprocessing import Process, Manager
import numpy as np

def f(lst, lst1):
    lst.append([2])
    a = np.array([[8],[9]])
    lst1 = np.array(a).tolist()
    print('lst1: ', lst1)

if __name__ == '__main__':

    manager = Manager()

    lst = manager.list()
    lst.append([1])
    print('lst main before: ', lst)

    lst1 = manager.list()
    lst1.append([7])
    print('lst1 main before: ', lst1)

    p = Process(target=f, args=(lst,lst1))
    p.start()
    p.join()

    print('lst main after: ', lst)
    print('lst1 main after: ', lst1)

Вывод:

lst main before:  [[1]]
lst1 main before:  [[7]]
lst1:  [[8], [9]]
lst main after:  [[1], [2]]
lst1 main after:  [[7]]

Ответы [ 2 ]

1 голос
/ 07 марта 2020

Параметр функции сам по себе является локальной переменной для функции.

Итак, в def f(lst, lst1): вы определяете две новые переменные с именами lst и lst1, которым присваиваются значения, которые вы называете функция с. Наименование переменных так же, как и переменные, которые вы передаете, не влияет на это. Фактически, хорошие Python редакторы, такие как PyCharm, будут предупреждать вас, когда вы будете делать это, вы «затеняете» глобальное.

Если вы измените список, назначенный lst1, это изменится список, на который указывает глобальный (это тот же список), но если вы назначите что-то новое для lst1, он больше не будет указывать на этот список, и вы не увидите изменения в глобальной переменной.

Например:

def change_and_assign(xs):
    # adds 'b' to the list pointed to by local xs, but also global; it's the same list
    xs.append('b')
    # assigns a new list to the local, but doesn't modify global xs
    xs = ['c']

xs = ['a']
change_and_assign(xs)
print(xs)

Будет напечатано ['a', 'b'], а не ['c'].

Вам следует либо вернуть значение, которое вы ищете, либо присвоить его глобальному значению, которое не не в тени (но я бы порекомендовал предыдущее):

def change_and_return_new(xs):
    # same as before
    xs.append('b')
    # function will return the value and return value can be assigned
    return ['c']

xs = ['a']
# assign return value to ys
ys = change_and_return_new(xs)
print(xs, ys)

def change_and_assign_global(xs):
    # declare that zs should be a global
    global zs
    # same as before
    xs.append('b')
    # assign a new list to the global zs
    zs = ['c']

xs = ['a']
# this will modify xs, but also create a global zs
change_and_assign_global(xs)
print(xs, zs)

Если вы не понимаете, что происходит, перечитайте и посмотрите, получите ли вы это, или посмотрите другую информацию о глобальном и локальном переменные и область видимости - это важно получить, если вы хотите написать Python код самостоятельно, без труда отследить ошибки.

0 голосов
/ 07 марта 2020

Я нашел решение, ответ уже был в коде и так просто, извините, что спросил:

a = np.array([[8],[9]])
lst2 = np.array(a).tolist()
L1.append(lst2)

вместо:

a = np.array([[8],[9]])
lst1 = np.array(a).tolist()
...