除非您跳出标准库,否则 Python 线程(和多处理)和酸洗会受到破坏和限制。
如果你使用一个名为pathos.multiprocesssing 的multiprocessing 的fork,你可以直接在multiprocessing 的map 函数中使用类和类方法。这是因为dill 被用来代替pickle 或cPickle,而dill 几乎可以在python 中序列化任何东西。 pathos.multiprocessing 提供了线程模块的接口,就像标准的 python 模块一样。
pathos.multiprocessing 还提供了一个异步映射函数……它可以map 具有多个参数的函数(例如map(math.pow, [1,2,3], [4,5,6]))
见:
What can multiprocessing and dill do together?
和:
http://matthewrocklin.com/blog/work/2013/12/05/Parallelism-and-Serialization/
>>> from pathos.multiprocessing import ProcessingPool as Pool
>>> #from pathos.multiprocessing import ThreadingPool as Pool
>>>
>>> p = Pool(4)
>>>
>>> def add(x,y):
... return x+y
...
>>> x = [0,1,2,3]
>>> y = [4,5,6,7]
>>>
>>> p.map(add, x, y)
[4, 6, 8, 10]
>>>
>>> class Test(object):
... def plus(self, x, y):
... return x+y
...
>>> t = Test()
>>>
>>> p.map(Test.plus, [t]*4, x, y)
[4, 6, 8, 10]
>>>
>>> p.map(t.plus, x, y)
[4, 6, 8, 10]
字典中有不寻常的东西,没关系……
>>> d = {'1':add, '2':t, '3':Test, '4':range(10), '5':1}
>>>
>>> def items(x):
... return x[0],x[1]
...
>>> p.map(items, d.items())
[('1', <function add at 0x103b7e2a8>), ('3', <class '__main__.Test'>), ('2', <__main__.Test object at 0x103b7ad90>), ('5', 1), ('4', [0, 1, 2, 3, 4, 5, 6, 7, 8, 9])]
顺便说一句,如果你想腌制线程锁,你也可以这样做。
>>> import dill as pickle
>>> import threading
>>> lock = threading.Lock()
>>>
>>> pickle.loads(pickle.dumps(lock))
<thread.lock object at 0x10c534650>
看起来您想构建某种闭包,自动将函数调用存储到文件或至少存储到序列化字符串。如果那是你想要的,
你可以试试klepto,它给你一个装饰器,你可以应用到你的函数中
您可以缓存到内存或磁盘或数据库。 Klepto 可以使用pickle或者json,
但它被dill 增强了,所以它可以在python 中序列化几乎任何东西——所以不要
担心你的字典里有什么……只需序列化它。
from klepto import lru_cache as memoize
from klepto.keymaps import picklemap
dumps = picklemap(serializer='dill')
class Adder(object):
"""A simple class with a memoized method"""
@memoize(keymap=dumps, ignore=('self','**'))
def __call__(self, x, *args, **kwds):
debug = kwds.get('debug', False)
if debug:
print ('debug:', x, args, kwds)
return sum((x,)+args)
add = __call__
add = Adder()
assert add(2,0) == 2
assert add(2,0,z=4) == 2 # cached (ignore z)
assert add(2,0,debug=False) == 2 # cached (ignore debug)
assert add(1,2,debug=False) == 3
assert add(1,2,debug=True) == 3 # cached (ignore debug)
assert add(4) == 4
assert add(x=4) == 4 # cached
Klepto 使您能够在重新启动代码时获得所有缓存的结果。
在这种情况下,你会选择一些文件或数据库后端,然后确保你对存档执行 add.dump()... 然后重新启动 python 或其他,然后执行 add.load() 以加载存档结果。
在此处获取代码:
https://github.com/uqfoundation