Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多处理-如何修改对象?_Python_Class_Object_Methods_Multiprocessing - Fatal编程技术网

Python多处理-如何修改对象?

Python多处理-如何修改对象?,python,class,object,methods,multiprocessing,Python,Class,Object,Methods,Multiprocessing,我的类嵌入了一个方法来处理对象。但当我使用多重处理时,原始对象不会被修改。更一般地说,如何使用对象的方法实现对象的多处理?(我使用python 3.8) 这是我的密码: from multiprocessing import Pool class MyObject(object): def __init__(self): self.level=1 def process(self): self.level=2 # and

我的类嵌入了一个方法来处理对象。但当我使用多重处理时,原始对象不会被修改。更一般地说,如何使用对象的方法实现对象的多处理?(我使用python 3.8)

这是我的密码:

from multiprocessing import Pool

class MyObject(object):
    def __init__(self):
        self.level=1
    
    def process(self):
        self.level=2
        # and other many things that modify the object...
    
if __name__ == "__main__":
    objects = [MyObject() for i in range(10)]
    pool = Pool(3)
    async_results = []
    for o in objects:
        async_results.append(pool.apply_async(o.process, [], {}))
    pool.close()
    for r in async_results:
        r.get()
    for o in objects:
        print(o.level)      # unfortunately, 1, not 2

多重处理序列化对象并将其发送到其他进程。然后,它返回序列化对象作为返回值。因此,这些远程进程无法在原始内存空间中修改您发送给它们的对象

取而代之的是,获取返回的对象
async_结果
并使用它们,或者,在此处使用这些结果中的数据修改
对象。

您只需创建“可代理”的托管对象,就像调用
多处理.Manager()时创建的
SyncManager
实例返回的对象一样
,例如托管的
dict
实例:

来自多处理导入池的

从multiprocessing.managers导入BaseManager、NamespaceProxy
从multiprocessing.pool导入池
类MyObject(对象):
定义初始化(自):
自我水平=1
def过程(自我):
自我水平=2
#和其他许多修改对象的东西。。。
def被授权人(自身):
回归自我
#如果要访问方法之外的属性,则必须显式创建自定义代理
#这迫使我们命名每种方法,例如过程:
类MyObjectProxy(NamespaceProxy):
_exposed_u=(“\uuuuu getattribute_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuugetattr_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
def过程(自我):
callmethod=NamespaceProxy.\uuuu getattribute\uuuuuuuu(self,\uCallMethod'))
返回callmethod('进程')
def被授权人(自身):
callmethod=NamespaceProxy.\uuuu getattribute\uuuuuuuu(self,\uCallMethod'))
返回callmethod('delegatee')
"""
或者,您可以对每个方法使用以下通用签名:
def流程(自身、*args、**kwds):
callmethod=NamespaceProxy.\uuuu getattribute\uuuuuuuu(self,\uCallMethod'))
返回callmethod('process',args,kwds)
"""
类MyObjectManager(BaseManager):
通过
如果名称=“\uuuuu main\uuuuuuuu”:
MyObjectManager.register('MyObject',MyObject,MyObjectProxy)
使用MyObjectManager()作为管理器:
objects=[manager.MyObject()用于范围(10)中的i]
池=池(3)
异步_结果=[]
对于对象中的o:
async_results.append(pool.apply_async(o.process,[],{}))
#或者只是:
#async_results.append(pool.apply_async(o.process))
pool.close()
对于异步_结果中的r:
r、 得到()
对于对象中的o:
打印(o级)
obj0=对象[0]
打印(类型(obj0))
delegatee=obj0.delegatee()
打印(类型(被授权人))
打印('delegatee level=',delegatee.level)
印刷品:

2
2
2
2
2
2
2
2
2
2
<class '__main__.MyObjectProxy'>
<class '__main__.MyObject'>
delegatee level = 2
2
2.
2.
2.
2.
2.
2.
2.
2.
2.
被授权人级别=2

但请注意,每个方法调用或属性访问都是通过代理进行的,或多或少相当于远程过程调用。

如果只涉及属性,这里有另一个解决方案,可能更简单:

from multiprocessing import Pool

class MyObject(object):
    def __init__(self, id):
        self.id = id
        self.level = 1
    
    def process(self):
        self.level = 2      # modified attribute
        self.name = "xxx"   # new attribute
        return self.__dict__
    
if __name__ == "__main__":
    objects = [MyObject(i) for i in range(10)]
    pool = Pool(3)
    async_results = []
    for o in objects:
        async_results.append(pool.apply_async(o.process, [], {}))
    pool.close()
    results=[]
    for r in async_results:
        results.append(r.get())
    for r in results:
        for o in objects:
            if o.id == r["id"]:
                o.__dict__.update(r)
                break
    for o in objects:
        print(o.__dict__)

可能与无法修改对象相关?我不这么认为。如果要传递的是对象的代理,该怎么办?您认为托管的
dict
实例(如
multiprocessing.Manager().dict()
返回的实例)如何工作?@Booboo这是个好主意。严格地说,parameter对象确实没有改变,但它确实实现了他想要的。parameter对象是一个对象(类MyObjectProxy),它最终委托给
MyObject
(实际上是
\UuMain\UuUuUuMyObject
)的一个实例,这是最明确的改变。并且可以获得该委托对象(“被委托人”);您只需要在
MyObject
中找到一个返回
self
的方法。我已经用演示更新了我的答案。