Pyparsing解析并列出typerror

时间:2018-08-15 12:08:16

标签: python pyparsing

对于一种小语言,我想解析X形式的表达式,其中YZVfrom pyparsing import * class Y(): def __init__(self, ls): self.ls = ls def MakeCombinedList(tokens): print(len(tokens)) # prints 4 print(tokens) # [5, 1, 2, 3] clist = tokens[1] clist.append(tokens[0]) # 'int' attribute object has no attribute 'append' return clist def MakeIntList(tokens): nlist = tokens[0].split(",") ilist = [] for n in nlist: ilist.append(int(n)) return ilist def MakeY(tokens): Yobj = Y(tokens[0]) return Yobj LEFT_BRACK = Suppress(Literal("[")) RIGHT_BRACK = Suppress(Literal("]")) NATURAL = Word(nums).addParseAction(lambda n: int(n[0])) NATURAL_LIST = delimitedList(NATURAL, combine = True) NATURAL_VEC = LEFT_BRACK + NATURAL_LIST + RIGHT_BRACK NATURAL_VEC.addParseAction(MakeIntList) X = NATURAL + NATURAL_VEC X.addParseAction(MakeCombinedList) Y = X Y.addParseAction(MakeY) print(Y.parseString("5 [1,2,3]").ls) 是自然数。

下面是我的尝试。

MakeIntList

"1,2,3"应该将诸如[1,2,3]之类的字符串转换为列表MakeCombinedList

然后,应该

tokens将一个整数添加到此列表,但是MakeCombinedList收到的MakeIntList不是单个整数,也不是从tokens[1]创建的整数列表,而是所有整数的列表,如我的评论所示。

如何使MakeCombinedList中的MakeIntList成为调用mypath='/Users/sachal/Desktop/data_raw/normal_1/images' onlyfiles = [ f for f in listdir(mypath) if isfile(join(mypath,f)) ] images = np.asarray(np.empty(len(onlyfiles), dtype=object)) for n in range(0, len(onlyfiles)): images[n] = cv2.imread( join(mypath,onlyfiles[n]) ) #-------------------------------------------------------------------------------- resized = np.asarray(np.empty(len(onlyfiles), dtype=object)) img_f = np.asarray(np.empty(len(onlyfiles), dtype=object)) for n in range(0, len(onlyfiles)): resized[n] = cv2.resize(images[n],(101,101)) img_f[n] = cv2.cvtColor(resized[n], cv2.COLOR_BGR2YUV) train_img = np.asarray(img_f) #-------------------------------------------------------------------------------- 的结果?

1 个答案:

答案 0 :(得分:2)

由于您使用第一行将单独的数字字符串解析为int,然后使用第二行将它们重新组合成一个逗号分隔的字符串,因此这两行是相互冲突的。

NATURAL = Word(nums).addParseAction(lambda n: int(n[0]))
NATURAL_LIST = delimitedList(NATURAL, combine=True)

您要查找的功能是Group

NATURAL = Word(nums).addParseAction(lambda n: int(n[0]))
NATURAL_LIST = Group(delimitedList(NATURAL))
NATURAL_VEC = LEFT_BRACK + NATURAL_LIST +  RIGHT_BRACK
# no MakeIntList parse action required

现在,您不用创建新的字符串,而是在解析操作中重新解析它,而是使用Group告诉pyparsing生成结果标记的子结构。

这里还有些混乱:

Y = X
Y.addParseAction(MakeY)

这会将Y从顶部定义的类重新定义为pyparsing表达式,并且在尝试访问其ls属性时会得到一些奇怪的回溯。

Y_expr = X
Y_expr.addParseAction(MakeY)

我编写了runTests方法,以使其更容易进行简单的表情测试和打印,而不必处理Py2 / Py3的打印差异:

Y_expr.runTests("""\
    5 [1,2,3]
    """)

显示:

5 [1,2,3]
[<__main__.Y object at 0x00000241C57B7630>]

由于您的Y类仅使用默认的__repr__行为,因此,如果您定义自己的类,则可以更好地查看内容:

class Y():
    def __init__(self, ls):
        self.ls = ls
    def __repr__(self):
        return "{}: {}".format(type(self).__name__, vars(self))

现在runTests显示:

5 [1,2,3]
[Y: {'ls': 5}]

如果Y类的目的只是为您提供已解析字段的属性名称,请考虑改用结果名称:

X = NATURAL('ls') + NATURAL_VEC

Y_expr = X
#~ Y_expr.addParseAction(MakeY)

# what you had written originally    
print(Y_expr.parseString("5 [1,2,3]").ls)

只需打印:

5