0

使用 pp 模块时无法更新对象“测试”中的字典“参数”。谁能告诉我为什么会这样?只看代码:

import pp

class test(object):
    params = {'n': None}
    dic2 = {}
    n = None

    def __init__(self, i):
        #won't change
        self.params['n'] = i
        #changed
        self.n = i
        self.dic2 = {i: i}

    def run(self):
        print self.n, self.params, self.dic2

job_server = pp.Server()

jobs = []

for i in xrange(10):
    t = test(i)
    #won't change
    t.params['n'] = i
    #changed
    t.n = i
    t.run()
    jobs.append(job_server.submit(t.run))

[job() for job in jobs]

结果:

0 {'n': 0} {0: 0}
1 {'n': 1} {1: 1}
2 {'n': 2} {2: 2}
3 {'n': 3} {3: 3}
4 {'n': 4} {4: 4}
0 {'n': None} {0: 0}
1 {'n': None} {1: 1}
2 {'n': None} {2: 2}
3 {'n': None} {3: 3}
4 {'n': None} {4: 4}

正如我们在使用 pp 时看到的,“params['n']”无法更新。这是一种奇怪的行为。这怎么可能发生?

4

1 回答 1

3

这是多处理模块的常见缺陷。

当您调用 likejob_server.submit(t.run)时,对象t会被腌制,发送到新进程,取消run腌制,执行并且返回值被腌制,发送回主进程并取消腌制。

现在,不真正支持类酸洗(参见此处)。pickle 只是腌制名称,并且在 unpickling 时重新导入模块以获取类对象。

由于您使用的变量是类变量,因此在重新导入模块时它们会重新初始化。函数的属性也会发生同样的情况。

如果要保留这些变量的值,则必须将它们设为实例变量。

于 2012-11-02T10:14:49.087 回答