所以我有这段代码:
def someFunction (S):
pass
if __name__ == "__main__":
import time
start = time.time()
G = nx.read_gpickle("../../graphs/graph.gpickle")
Ep = dict()
with open("Ep.txt") as f:
for line in f:
data = line.split()
Ep[(int(data[0]), int(data[1]))] = float(data[2])
pool = None
def mapAvgSize (S):
return avgIAC(G, S, Ep, I)
if pool == None:
pool = multiprocessing.Pool(processes=4)
print 'Start Initialization...'
S = []
print 'Selecting S...'
print 'before pool.map'
Ts = pool.map(mapAvgSize, [S]*4)
print 'after pool.map'
看起来一切都是正确的:我在池之前定义了函数,将所有内容都放在 if __name__ == "__main__":
语句下。但不幸的是,上面的代码执行到 print 'before pool.map'
行,然后抛出错误:
AttributeError: 'module' object has no attribute 'mapAvgSize'
最奇怪的是,上面的代码在 Linux 下工作,但在 Windows 上失败(我想在我的笔记本电脑外在具有更多内核的计算机上测试它)。
任何有助于弄清楚为什么代码在 Windows 上失败的帮助都将受到赞赏和支持。
最佳答案
如前所述,您需要使 mapAvg
成为顶级函数。由于它目前关闭了一些“本地”变量,因此您也需要修复此问题。您可以使用初始化器(mapped
+ initializer
在示例中)传递那些当前关闭的变量,或者将它们传递给您正在映射的迭代器(mapped2
)
示例,展示(部分)您的选择:
import multiprocessing
globalB = None
def mapped(a):
global globalB
return a * globalB
def initializer(*args):
global globalB
globalB, = args
def mapped2(args):
a, b = args
return a * b
if __name__ == "__main__":
myB = 2
pool = multiprocessing.Pool(processes=5,
initializer=initializer,
initargs=(myB,)
)
# Using the initializer provided globalB
for i in pool.map(mapped, range(10)):
print i
# directly provided as an arg
for i in pool.map(mapped2, ((a, myB) for a in range(10))):
print i
在您的代码中,您当然可以将 Ep
、G
(以及任何 I
)移动到顶层,但是你会导致每个池进程的文件 I/O,所以如果我必须实现它,我会正确地使用类似 mapped2
的东西(使用专用的队列项类而不是一些元组)。
PS:这甚至可以在 Linux 上运行(有时?!)的原因似乎是 fork()
工作方式的意外结果。你不应该依赖它。
关于python - Windows 中 pool.map 的属性错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24679740/