我正在尝试使用multiprocessing.pool
加速对使用pyparsing
解析的文件进行一些解析,但每次尝试时都会收到multiprocessing.pool.MaybeEncodingError
异常。
我已将其缩小到与返回字典(ParseResults.asDict()
)有关,使用asList()
错误不会发生;但我实际解析的输入非常复杂,所以理想情况下我想使用asDict
。
正在解析的实际数据是标记元组的Erlang列表,我想将其映射到python列表。这个语法非常复杂,所以我得到了一个简化的测试用例(更新为包含嵌套字典):
#!/usr/bin/env python2.7
from pyparsing import *
import multiprocessing
dictionary = Forward()
key = Word(alphas)
sep = Suppress(":")
value = ( key | dictionary )
key_val = Group( key + sep + value )
dictionary <<= Dict( Suppress('[') + delimitedList( key_val ) + Suppress(']') )
def parse_dict(s):
p = dictionary.parseString(s).asDict()
return p
def parse_list(s):
return dictionary.parseString(s).asList()
# This works (list)
data = ['[ foo : [ bar : baz ] ]']
pool = multiprocessing.Pool()
pool.map(parse_list, data)
# This fails (dict)
pool.map(parse_dict, data)
失败:
Traceback (most recent call last):
File "lib/python/nutshell/multi_parse.py", line 19, in <module>
pool.map(parse, data)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 250, in map
return self.map_async(func, iterable, chunksize).get()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 554, in get
raise self._value
multiprocessing.pool.MaybeEncodingError: Error sending result: '[{'foo': ([(['bar', 'baz'], {})], {'bar': [('baz', 0)]})}]'. Reason: 'TypeError("'str' object is not callable",)'
答案 0 :(得分:2)
更新:自更新以来,此问题已发生重大变化。不可挑选的原始观点仍然存在并留在下面。
你在语法中说你使用的是delimitedList
,所以让我们将它添加到我们的测试用例中:
data = ['[ foo : [ bar : baz ], cat:dog ]']
你的“dictionary
”语法对象没有理由是python dict,它是一个列表。如果您不是故意要将delimitedList
更改为其他内容。我已经更新了语法,允许使用parseAction
:
dictionary = Forward()
key = Word(alphas)
LP, RP, sep = map(Suppress, "[]:")
value = key | dictionary
key_val = key("key") + sep + value("val")
dictionary <<= LP + delimitedList( key_val ) + RP
def parse_key_val(x): return {x.key:x.val}
key_val.setParseAction(parse_key_val)
def parse_dict(s):
# Yes, it's a list, not a dict!
return dictionary.parseString(s).asList()
def parse_list(s):
return dictionary.parseString(s).asList()
这提供了一个平行的工作答案:
[[{'foo': {'bar': 'baz'}}, {'cat': 'dog'}]]
原始回答: 我认为多处理失败,因为它不能腌制对象。你认为你有一个词典,但如果你看一下:
def parse_dict(s):
val = lang.parseString(s).asDict()
print type(val["foo"])
return val
你会发现内部类型是<class 'pyparsing.ParseResults'>
。我不确定如何递归地应用pp.Dict
,但一个非常简单的修复就是改变你的语法:
value = ( Word(alphas) )
sep = Suppress(":")
key_val = Group( value + sep + value )
lang = Dict( Suppress('[') + delimitedList( key_val ) + Suppress(']') )
现在允许pp.Dict
正常运行。对于它的价值,我发现我的许多多处理问题来自一个无法正确序列化的对象,所以它通常是我看的第一个地方。
一个有用且相关的问题: