【问题标题】:Pattern for associating pyparsing results with a linked-list of nodes将 pyparsing 结果与节点链表关联的模式
【发布时间】:2011-08-03 09:21:41
【问题描述】:

我已经定义了一个pyparsing 规则来将此文本解析为语法树...

文本命令:

add Iteration name = "Cisco 10M/half"
    append Observation name = "packet loss 1"
        assign Observation results_text = 0.0
        assign Observation results_bool = True
        append DataPoint
            assign DataPoint metric = txpackets
            assign DataPoint units = packets
        append DataPoint
            assign DataPoint metric = txpackets
            assign DataPoint units = packets
    append Observation name = "packet loss 2"
        append DataPoint
            assign DataPoint metric = txpackets
            assign DataPoint units = packets
        append DataPoint
            assign DataPoint metric = txpackets
            assign DataPoint units = packets

语法树:

['add', 'Iteration', ['name', 'Cisco 10M/half']]
['append', 'Observation', ['name', 'packet loss 1']]
['assign', 'Observation', ['results_text', '0.0']]
['assign', 'Observation', ['results_bool', 'True']]
['append', 'DataPoint']
['assign', 'DataPoint', ['metric', 'txpackets']]
['assign', 'DataPoint', ['units', 'packets']]
...

我正在尝试将上面语法树中的所有嵌套键值对关联到对象的链接列表中...层次结构看起来像这样(每个单词都是namedtuple...孩子在层次结构中是在父母的孩子名单上):

Log: [ 
    Iteration: [ 
        Observation: 
            [DataPoint, DataPoint], 
        Observation: 
            [DataPoint, DataPoint]
    ]
]

所有这一切的目标是构建一个通用的测试数据采集平台,以驱动针对网络设备的测试流程,并记录结果。数据采用这种格式后,将使用相同的数据结构来构建测试报告。为了回答下面 cmets 中的问题,我选择了一个链表,因为它似乎是编写报告时顺序出列信息的最简单方法。但是,我宁愿在完成测试之前不分配IterationObservation 序列号......以防我们在进行测试的过程中发现问题并插入更多观察。我的理论是列表中每个元素的位置就足够了,但如果这是问题的一部分,我愿意改变它。

问题是我在构建后尝试将键值分配给链表中的对象时迷失了方向。例如,在我将Observation namedtuple 插入第一个Iteration 后,我无法可靠地处理上例中assign Observation results_bool = True 的更新。

是否有通用的设计模式来处理这种情况?我已经用谷歌搜索了一段时间,但我似乎无法在解析文本(我可以做到)和管理数据层次结构(主要问题)之间建立联系。超链接或小演示代码都可以……我只需要指针就能走上正轨。

【问题讨论】:

  • 至于术语:您在第二个代码块中拥有的只是解析的结果。它可以被认为是一个非常基本的抽象语法树。前一个块只是输入、源代码等。
  • @delnan,感谢您的更正。
  • 您能否详细介绍一下您决定使用链表的原因?您尝试使用此解析数据实现的最终结果是什么?
  • @jathanism - 我认为 Mike 说的是“链接”但意思是“嵌套” - 数据应该反映与输入中的缩进级别相对应的层次结构(我猜)。

标签: python parsing design-patterns linked-list pyparsing


【解决方案1】:

我不知道您正在寻找的实际设计模式,但我对手头的问题充满热情。我大量使用网络设备,解析和组织数据对我来说是一个巨大的持续挑战。

很明显,问题不在于解析数据,而在于你之后如何处理它。这是您需要考虑附加到已解析数据的含义的地方。如果包含列表的对象也有意义,那么嵌套列表方法可能对您很有效。

Namedtuples 非常适合快速而肮脏的类行为,但是当您需要它们执行基本属性访问之外的任何操作时,它们就会失败,特别是考虑到它们作为元组是不可变的。在我看来,您可能想用成熟的类替换某些 namedtuple 对象。通过这种方式,您可以高度自定义可用的行为和方法。

例如,您知道 Iteration 将始终包含 1 个或多个 Observation 对象,然后将包含 1 个或多个 DataPoint 对象。如果您可以准确地描述这些关系,那么这将使您走上处理它们的道路。

【讨论】:

  • @jathanism...namedtuples 只是半不可变的...它们有一个_replace() 方法可以让您覆盖值。我还将子关系实现为附加到namedtuple 属性的标准list() 对象。我以前解决过一个类似的问题 - ciscoconfparse,但这实际上是我第一次涉足 python / 这种解析(我在一个 perl 模块失败后的一个周末把它搞砸了);在学习了更多的语言后,我知道这是一项多么糟糕的工作。我想重新开始,如果可能的话,要有一个好的设计。
  • 您可以使用 namedtuples 做到这一点,但这并不能帮助您解决手头的问题,这似乎仍然表明您的解析输出的含义和结构使用是您的问题所在。
【解决方案2】:

我最终使用了textfsm,它允许我在解析配置文件时保持不同行之间的状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-21
    相关资源
    最近更新 更多