Python 中的 Class 池
Pool within a Class in Python
我想在 class 中使用池,但似乎有问题。我的代码很长,我创建了一个小型演示变体来说明问题。如果您能给我一个可用的下面代码的变体,那就太好了。
from multiprocessing import Pool
class SeriesInstance(object):
def __init__(self):
self.numbers = [1,2,3]
def F(self, x):
return x * x
def run(self):
p = Pool()
print p.map(self.F, self.numbers)
ins = SeriesInstance()
ins.run()
输出:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 504, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 319, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
然后挂起。
看起来由于函数传递给工作线程的方式(pickling),你不能不幸地使用实例方法。我的第一个想法是使用 lambda,但结果是内置 pickler can't serialize those either. 解决方案,不幸的是,只是在全局命名空间中使用一个函数。正如其他答案中所建议的,您可以使用静态方法并传递 self 使其看起来更像实例方法。
from multiprocessing import Pool
from itertools import repeat
class SeriesInstance(object):
def __init__(self):
self.numbers = [1,2,3]
def run(self):
p = Pool()
squares = p.map(self.F, self.numbers)
multiples = p.starmap(self.G, zip(repeat(self), [2, 5, 10]))
return (squares, multiples)
@staticmethod
def F(x):
return x * x
@staticmethod
def G(self, m):
return [m *n for n in self.numbers]
if __name__ == '__main__':
print(SeriesInstance().run())
您还可以在 class.
中使用带有静态函数的多处理
您有一个错误,因为 pickle 无法序列化 instancemethod。所以你应该使用这个小的解决方法:
from itertools import repeat
from multiprocessing import Pool
class SeriesInstance:
def __init__(self):
self.numbers = [1, 2, 3]
def F(self, x):
return x * x
def run(self):
p = Pool()
print(list(p.starmap(SeriesInstance.F, zip(repeat(self), self.numbers))))
if __name__ == '__main__':
SeriesInstance().run()
我想在 class 中使用池,但似乎有问题。我的代码很长,我创建了一个小型演示变体来说明问题。如果您能给我一个可用的下面代码的变体,那就太好了。
from multiprocessing import Pool
class SeriesInstance(object):
def __init__(self):
self.numbers = [1,2,3]
def F(self, x):
return x * x
def run(self):
p = Pool()
print p.map(self.F, self.numbers)
ins = SeriesInstance()
ins.run()
输出:
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 551, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.7/threading.py", line 504, in run
self.__target(*self.__args, **self.__kwargs)
File "/usr/lib64/python2.7/multiprocessing/pool.py", line 319, in _handle_tasks
put(task)
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed
然后挂起。
看起来由于函数传递给工作线程的方式(pickling),你不能不幸地使用实例方法。我的第一个想法是使用 lambda,但结果是内置 pickler can't serialize those either. 解决方案,不幸的是,只是在全局命名空间中使用一个函数。正如其他答案中所建议的,您可以使用静态方法并传递 self 使其看起来更像实例方法。
from multiprocessing import Pool
from itertools import repeat
class SeriesInstance(object):
def __init__(self):
self.numbers = [1,2,3]
def run(self):
p = Pool()
squares = p.map(self.F, self.numbers)
multiples = p.starmap(self.G, zip(repeat(self), [2, 5, 10]))
return (squares, multiples)
@staticmethod
def F(x):
return x * x
@staticmethod
def G(self, m):
return [m *n for n in self.numbers]
if __name__ == '__main__':
print(SeriesInstance().run())
您还可以在 class.
中使用带有静态函数的多处理您有一个错误,因为 pickle 无法序列化 instancemethod。所以你应该使用这个小的解决方法:
from itertools import repeat
from multiprocessing import Pool
class SeriesInstance:
def __init__(self):
self.numbers = [1, 2, 3]
def F(self, x):
return x * x
def run(self):
p = Pool()
print(list(p.starmap(SeriesInstance.F, zip(repeat(self), self.numbers))))
if __name__ == '__main__':
SeriesInstance().run()