首页 > 解决方案 > pyparsing 语法以提取 Python 片段的部分

问题描述

我有一个 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,
    )

我想定义一个语法,它可以让我查看函数参数列表中的键值对,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(),
...]

我尝试执行以下操作:

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

parameters.transformString(python_snippet)

输出setParseAction为:

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

任何帮助将不胜感激。

标签: pythonpyparsing

解决方案


正如 mkrieger1 所说,您可以使用ast内置的 Python 库。

在 Python 3.9(或更高版本)中,有可以将转换为字符串的ast.unparse函数。ast.Node

import ast

mycode = """\
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,
    )
"""

root = ast.parse(mycode)
calls = [n for n in ast.walk(root) if isinstance(n, ast.Call)]
first_call = calls[0]
target_list = [(k.arg, ast.unparse(k.value)) for k in first_call.keywords]
print(target_list)

这使

[
   ('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')
]

推荐阅读