gpt4 book ai didi

Python:从该类内部对作为该类数据成员的函数进行多处理的有效解决方法

转载 作者:太空狗 更新时间:2023-10-29 20:48:05 26 4
gpt4 key购买 nike

我知道 various discussionslimitations在处理作为类的数据成员的函数时(由于 Pickling 问题),多处理模块的使用。

但是是否有另一个模块,或者多处理中的任何类型的解决方法,允许特别像下面的东西(特别是不强制并行应用函数的定义以存在于类之外)?

class MyClass():

def __init__(self):
self.my_args = [1,2,3,4]
self.output = {}

def my_single_function(self, arg):
return arg**2

def my_parallelized_function(self):
# Use map or map_async to map my_single_function onto the
# list of self.my_args, and append the return values into
# self.output, using each arg in my_args as the key.

# The result should make self.output become
# {1:1, 2:4, 3:9, 4:16}


foo = MyClass()
foo.my_parallelized_function()
print foo.output

注意:我可以通过将 my_single_function 移到类之外并将类似 foo.my_args 的内容传递给 mapmap_async 命令。但这会将函数的并行执行推到 MyClass 的实例之外。

对于我的应用程序(并行化检索、连接和清理每月横截面数据的大数据查询,然后将它们附加到此类横截面的长时间序列中),拥有这个非常重要类内的功能 因为我的程序的不同用户将用不同的时间间隔、不同的时间增量、要收集的不同数据子集等来实例化类的不同实例,所以这些都应该是与该实例相关联。

因此,我希望并行化的工作也由实例来完成,因为它拥有与并行化查询相关的所有数据,并且尝试编写一些绑定(bind)到某些参数的 hacky 包装函数是愚蠢的,并且生活在类之外(特别是因为这样的功能是非通用的。它需要来自类内部的各种细节。)

最佳答案

史蒂文·贝萨德 has posted a way允许方法被 pickled/unpickled。你可以这样使用它:

import multiprocessing as mp
import copy_reg
import types

def _pickle_method(method):
# Author: Steven Bethard
# http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
func_name = method.im_func.__name__
obj = method.im_self
cls = method.im_class
cls_name = ''
if func_name.startswith('__') and not func_name.endswith('__'):
cls_name = cls.__name__.lstrip('_')
if cls_name:
func_name = '_' + cls_name + func_name
return _unpickle_method, (func_name, obj, cls)

def _unpickle_method(func_name, obj, cls):
# Author: Steven Bethard
# http://bytes.com/topic/python/answers/552476-why-cant-you-pickle-instancemethods
for cls in cls.mro():
try:
func = cls.__dict__[func_name]
except KeyError:
pass
else:
break
return func.__get__(obj, cls)

# This call to copy_reg.pickle allows you to pass methods as the first arg to
# mp.Pool methods. If you comment out this line, `pool.map(self.foo, ...)` results in
# PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup
# __builtin__.instancemethod failed

copy_reg.pickle(types.MethodType, _pickle_method, _unpickle_method)

class MyClass(object):

def __init__(self):
self.my_args = [1,2,3,4]
self.output = {}

def my_single_function(self, arg):
return arg**2

def my_parallelized_function(self):
# Use map or map_async to map my_single_function onto the
# list of self.my_args, and append the return values into
# self.output, using each arg in my_args as the key.

# The result should make self.output become
# {1:1, 2:4, 3:9, 4:16}
self.output = dict(zip(self.my_args,
pool.map(self.my_single_function, self.my_args)))

然后

pool = mp.Pool()   
foo = MyClass()
foo.my_parallelized_function()

产量

print foo.output
# {1: 1, 2: 4, 3: 9, 4: 16}

关于Python:从该类内部对作为该类数据成员的函数进行多处理的有效解决方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11726809/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com