You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用pyparsing提取HiveExecOperator顶层参数不拆分嵌套结构

问题描述

现有如下HiveExecOperator的Python调用示例代码:

fn = HiveExecOperator(
        task_id="abc",
        hql="abc.hql",
        dq_sql=DQCheck("pqr")
        .is_within_range(
            "COUNT(DISTINCT billing_association_type)",
            "type_cnts",
            lower=1.0,
            upper=float("inf"),
        )
        .build(),
        dag=main_dag,
    )

需求是提取该函数参数列表的顶层键值对,不拆分嵌套函数、链式调用结构,比如dq_sql对应的完整DQCheck链式调用要作为单个值返回,期望输出格式如下:

[task_id="abc", 
 hql="abc.hql",
 ...
 dq_sql=DQCheck("pqr")
        .is_within_range(
            "COUNT(DISTINCT billing_association_type)",
            "type_cnts",
            lower=1.0,
            upper=float("inf"),
        )
        .build(),
...]

当前尝试的语法规则存在问题:

assignment = variable + '=' + "HiveExecOperator" + nestedExpr('(', ')').setParseAction(lambda x: print(x))

parameters.transformString(python_snippet)

错误表现:setParseAction输出的结果把嵌套的is_within_range内部的lower、upper等参数也当成顶层键值对拆分了出来,错误输出如下:

['fn', '=', 'HiveExecOperator(']
['task_id', '=', '"abc",']
['hql', '=', '"abc.hql",']
['dq_sql', '=', 'DQCheck("stage.billing_associations")']
['lower', '=', '1.0,']
['upper', '=', 'float("inf"),']
...
解决方案

你现在的问题核心是没有区分顶层逗号和嵌套结构内的逗号,且没有把链式调用识别为完整值。按如下规则调整即可实现需求:

首先定义可以完整匹配嵌套结构、链式调用的值规则,再单独匹配顶层的键值对,调整后的代码如下:

import pyparsing as pp

# 基础元素定义
string = pp.dblQuotedString() | pp.sglQuotedString()
number = pp.pyparsing_common.number
identifier = pp.pyparsing_common.identifier

# 匹配任意层级的嵌套括号内容
nested_parens = pp.nestedExpr('(', ')')

# 定义值的匹配规则:支持链式调用、多层嵌套
value = pp.Forward()
# 链式调用后缀:.方法名 + 可选的参数括号
attr_call = pp.Combine('.' + identifier + pp.Optional(nested_parens))
# 基础值单元:字符串/数字/变量名/嵌套括号内容
value_atom = string | number | identifier | nested_parens
# 完整值:基础单元 + 任意数量的链式调用后缀
value << pp.Combine(value_atom + pp.ZeroOrMore(attr_call), adjacent=False, joinString=' ')

# 顶层参数规则:参数名 = 值 + 可选逗号
top_param = pp.Group(identifier + '=' + value + pp.Optional(','))

# 完整的HiveExecOperator调用匹配规则
hive_op_call = 'HiveExecOperator' + '(' + pp.ZeroOrMore(top_param) + ')'

# 执行解析
parse_result = hive_op_call.parseString(python_snippet)
# 提取顶层参数列表,过滤前后的括号标识
top_params = parse_result[2:-1]

# 输出验证
for item in top_params:
    print(f"{item[0]}={item[2]}")

核心逻辑说明:

  • 嵌套括号内的所有内容会被nestedExpr作为整体匹配,不会拆分内部的键值对
  • 链式调用的.方法()结构会被识别为值的一部分,和前面的对象合并成单个值
  • 仅顶层的参数名=值结构会被识别为参数,嵌套结构内的赋值符不会被误判

运行后得到的top_params就是你需要的顶层键值对列表,dq_sql对应的完整DQCheck链式调用会作为单个值返回。

内容的提问来源于stack exchange,提问作者user3138594

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:24:01