微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多处理时如何让 Python 尊重可迭代字段?

如何解决多处理时如何让 Python 尊重可迭代字段?

抱歉,如果这是一个愚蠢的问题,但我还没有找到解决这个问题的优雅方法。基本上,当使用 concurent.futures 模块时,类的非静态方法看起来应该可以正常工作,我在该模块的文档中没有看到任何暗示它们无法正常工作的内容,并且该模块不会产生任何运行时出错 - 甚至在许多情况下产生预期的结果!

但是,我注意到该模块似乎不尊重在父线程中对可迭代字段进行的更新,即使这些更新发生在启动任何子进程之前。这是我的意思的一个例子:

import concurrent.futures


class Thing:
    data_list = [0,0]
    data_number = 0

    def foo(self,num):
        return sum(self.data_list) * num

    def bar(self,num):
        return num * self.data_number


if __name__ == '__main__':
    thing = Thing()
    thing.data_list[0] = 1
    thing.data_number = 1

    with concurrent.futures.ProcesspoolExecutor() as executor:
        results = executor.map(thing.foo,range(3))
        print('result of changing list:')
        for result in results:
            print(result)

        results = executor.map(thing.bar,range(3))
        print('result of changing number:')
        for result in results:
            print(result)

我希望这里的结果是

result of changing list:
0
1
2
result of changing number:
0
1
2

但我得到了

result of changing list:
0
0
0
result of changing number:
0
1
2

因此,出于某种原因,对于只是整数的字段,事情按预期工作,但对于列表字段则完全不符合预期。这意味着在调用子进程时不考虑对列表所做的更新,即使对更简单的字段进行了更新。我也用 dicts 尝试过同样的问题,我怀疑这是所有可迭代对象的问题。

有什么方法可以使这项工作按预期进行,从而允许子进程尊重对可迭代字段的更新?非静态方法的多处理会像这样实现一半,这似乎很奇怪,但我希望我只是遗漏了一些东西!

解决方法

该问题与“尊重可迭代字段”无关,但这是一个相当微妙的问题。在您的主要流程中,您有:

thing.data_list[0] = 1 # first assignment
thing.data_number = 1 # second assignmment

而不是:

Thing.data_list[0] = 1 # first assignment
Thing.data_number = 1 # second assignment

就第一个赋值而言,没有任何实质性区别,因为在任何一个版本中,您都不是修改类属性,而是修改列表中碰巧被类属性引用的元素。换句话说,Thing.data_list 仍然指向同一个列表;此参考未更改。这是一个重要的区别。

但是在您的代码版本的第二个分配中,您实际上已经通过实例的 self 引用修改了类属性。当您这样做时,您正在创建一个具有相同名称的新实例属性data_number

您的类成员函数 foobar 正在尝试通过 self 访问类属性。 Thing 实例 thing 将被腌制到新的地址空间,但是当 Thing取消腌制,默认情况下将创建新的类属性并将其初始化为它们的默认值,除非您添加特殊的pickle 规则。但是实例属性应该是传输成功的,比如你新创建的data_number。这就是为什么“更改号码的结果:”会按照您的预期打印出来,即您实际上正在访问 data_number 中的 instance 属性 bar

bar 更改为以下内容,您将看到所有内容都将打印为 0

    def bar(self,num):
        return num * Thing.data_number

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?