具有多个函数的python全局变量错误

时间:2017-10-11 01:28:05

标签: python python-3.x multiprocessing global-variables python-multiprocessing

我这里有一个使用全局变量的示例代码,它给了我错误。在调用x函数之前,在test3函数中声明了全局变量test2,但test2函数似乎没有得到全局变量{{1}的定义}

x

错误是:

from multiprocessing import Pool
import numpy as np

global x    

def test1(w, y):
    return w+y    

def test2(v):
    global x        # x is assigned value in test3 before test2 is called
    return test1(x, v)    

def test3():
    global x
    x = 2
    y = np.random.random(10)
    with Pool(processes=6) as p:
        z = p.map(test2, y)
    print(z)

if __name__ == '__main__':
    test3()

我已经在SO上查看了很多问题和答案,但仍然无法弄清楚如何修复此代码。如果有人能指出代码有什么问题,将不胜感激?

任何人都可以告诉我如何重写上面的代码,而不更改代码的基本结构(即保留multiprocessing.pool.RemoteTraceback: """ Traceback (most recent call last): File "C:\WinPython-64bit-3.5.2.1Qt5\python-3.5.2.amd64\lib\multiprocessing\pool.py", line 119, in worker result = (True, func(*args, **kwds)) File "C:\WinPython-64bit-3.5.2.1Qt5\python-3.5.2.amd64\lib\multiprocessing\pool.py", line 44, in mapstar return list(map(*args)) File "...\my_global_variable_testcode.py", line 23, in test2 return test1(x, v) NameError: name 'x' is not defined """ The above exception was the direct cause of the following exception: Traceback (most recent call last): File "...\my_global_variable_testcode.py", line 35, in <module> test3() File "...\my_global_variable_testcode.py", line 31, in test3 z = p.map(test2, y) File "C:\WinPython-64bit-3.5.2.1Qt5\python-3.5.2.amd64\lib\multiprocessing\pool.py", line 260, in map return self._map_async(func, iterable, mapstar, chunksize).get() File "C:\WinPython-64bit-3.5.2.1Qt5\python-3.5.2.amd64\lib\multiprocessing\pool.py", line 608, in get raise self._value NameError: name 'x' is not defined test1test2作为3个单独的函数,就像我原来的一样代码这些函数是如此长而复杂)以便我可以实现我的多处理目标?

P.S。这个示例代码只是我实际代码的简化版本,我在这里给出了这个简化版本,以弄清楚如何使全局变量工作(而不是试图找到test3的复杂方法)。

*编辑* - 播放说明

这个赏金是为了帮助我重写这段代码的人,保留了代码中函数的基本结构:

(i)2+np.random.random(10)test1进行多处理调用,test2依次调用test2

(ii)使用全局变量或多处理模块的Manager类或其他任何东西来避免让test3将公共变量传递给test1

(iii)test2在调用多处理代码之前还给出一些值或对全局变量/公共数据进行更改

(iv)代码应该在Windows上运行(因为我使用的是Windows)。目前还没有寻找适用于Linux / OSX的解决方案。

为了帮助获得赏金,让我给出两个不同的测试用例。

*案例1 - 非多处理版本*

test1

输出(正确)是:

import numpy as np

x = 3

def test1(w, y):
    return w+y

def test2(v):
    global x
    print('x in test2 = ', x)
    return test1(x, v)

def test3():
    global x
    x = 2
    print('x in test3 = ', x)
    y = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    z = test2(y)
    print(z)

if __name__ == '__main__':
    test3()

*案例2 - 多处理版*

x in test3 =  2
x in test2 =  2
[ 3  4  5  6  7  8  9 10 11 12]

输出(不正确)是

from multiprocessing import Pool
import numpy as np

x = 3

def test1(w, y):
    return w+y

def test2(v):
    global x
    print('x in test2 = ', x)
    return test1(x, v)

def test3():
    global x
    x = 2
    print('x in test3 = ', x)
    y = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    with Pool(processes=6) as p:
        z = p.map(test2, y)
    print(z)

if __name__ == '__main__':
    test3()

2 个答案:

答案 0 :(得分:2)

你必须在函数外部定义变量x,例如代替全局x,比如说x = 0或者你喜欢的任何东西,并在函数中使用全局声明,就像你现在正在做的那样。 希望有所帮助

答案 1 :(得分:2)

您的问题是您在Process中共享变量而不在Multiprocess池中共享。使用global x时,它可以在单个进程中工作,但不能跨多个进程工作。在这种情况下,您需要使用Value中的multiprocessing。下面是一个更新的代码,适用于多处理

from multiprocessing import Pool, Value
import numpy as np

xVal = Value('i', 0)

def test1(w, y):
    return w+y

def test2(v):
    x = xVal.value
    print('x in test2 = ', x)
    return test1(x, v)

def test3():
    xVal.value = 2

    print('x in test3 = ', xVal.value)
    y = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    with Pool(processes=6) as p:
        z = p.map(test2, y)
    print(z)

if __name__ == '__main__':
    test3()

程序的输出如下

x in test3 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
x in test2 =  2
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

修改-2

以下程序应该在Windows上运行

from multiprocessing import Pool, Value, Manager, Array
import multiprocessing
import numpy as np

xVal = None

def sharedata(sharedData):
    global xVal
    xVal = sharedData

def test1(w, y):
    return w+y

def test2(v):
    global xVal
    x = xVal.value
    print('x in test2 = ', x)
    return test1(x, v)


def test3():
    xVal.value = 2
    print('x in test3 = ', xVal.value)
    y = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
    with Pool(processes=6, initializer=sharedata,initargs=(xVal,)) as p:
        z = p.map(test2, y)
    print('x in test3 = ', xVal.value)
    print(z)

if __name__ == '__main__':
    xVal = Value('i', 0)
    test3()