在 Python 3.5.1 中酸洗 ParseResult 时出错

Error when pickling ParseResult in Python 3.5.1

我的测试代码在 Python 2.7.11 中有效,但在 Python 3.5.1 中失败:

import pyparsing as pp
import pickle

class Greeting():
    def __init__(self, toks):
        self.salutation = toks[0]
        self.greetee = toks[1]

word = pp.Word(pp.alphas+"'.")
salutation = pp.OneOrMore(word)
comma = pp.Literal(",")
greetee = pp.OneOrMore(word)
endpunc = pp.oneOf("! ?")
greeting = salutation + pp.Suppress(comma) + greetee + pp.Suppress(endpunc)
greeting.setParseAction(Greeting)

string = 'Good morning, Miss Crabtree!'

g = greeting.parseString(string)

pkl = 'test .pkl'
pickle.dump(g, open(pkl, 'wb'))
pickle.load(open(pkl, 'rb'))

报错信息如下:

Traceback (most recent call last):
File "C:/Users/Arne/parser/test.py", line 23, in <module>
   pickle.load(open(pkl, 'rb'))
TypeError: __new__() missing 1 required positional argument: 'toklist'

__new__()指的是pyparsing.ParseResults.__new__(cls, toklist, name=None, asList=True, modal=True ).

在 Python 3.5.1 中,pyparsing 返回的对象通常仍然可以 pickle 还是有什么变化?

有人可以提供他们使用 picklepyparsing 2.0.7 的简短代码示例吗?

我真正的语法需要几分钟的时间来解析,所以我真的很感激能够在进一步处理之前存储结果。

这会因 protocol=2pickle.dump 的可选第三个参数)而失败,但如果您使用 pickle protocol = 0 或 1,则会通过。在 Python 2.7.10 , 0 是默认协议。在 Python 3.5 上,pickle 具有协议 0-4,同样,pickling ParseResults 仅适用于协议 0 和 1。但是在 Py3.5 中,默认协议已更改为 3。您现在可以解决此问题通过指定协议 0 或 1。

有关 pickle 协议的更多信息,请访问 https://docs.python.org/3/library/pickle.html?highlight=pickle#data-stream-format