ast 抽象语法树 解析python代码,字符串拆分,命令拆分

def parse_input(input_str):
    """
    解析输入字符串,提取变量名、方法路径、参数和右侧值。
    """
    tree = ast.parse(input_str)
    # 将 AST 转换为字符串

    output_name = None
    method_path = None
    converted_args = []
    right_value = None

    for node in ast.walk(tree):
        # 检查是否是赋值语句
        if isinstance(node, ast.Assign):
            # 提取目标变量名或属性路径
            if isinstance(node.targets[0], ast.Name):  # 普通变量名
                output_name = node.targets[0].id
            elif isinstance(node.targets[0], ast.Attribute):  # 属性赋值
                output_name = extract_attribute_path(node.targets[0])
            else:
                raise TypeError(f"Unsupported target type: {type(node.targets[0])}")

            # 提取右侧值
            right_value = extract_right_value(node.value)

            # 如果右侧是函数调用,提取方法路径和参数
            if isinstance(node.value, ast.Call):
                method_path, converted_args = extract_method_and_args(node.value)

        # 检查是否是直接的函数调用
        elif isinstance(node, ast.Call):
            method_path, converted_args = extract_method_and_args(node)

    return output_name, method_path, converted_args, right_value


def extract_method_and_args(call_node):
    """
    从函数调用节点中提取方法路径和参数。
    """
    # 提取方法路径
    if isinstance(call_node.func, ast.Attribute):  # 方法调用
        method_path = extract_attribute_path(call_node.func)
    elif isinstance(call_node.func, ast.Name):  # 普通函数调用
        method_path = call_node.func.id
    else:
        raise TypeError(f"Unsupported function type: {type(call_node.func)}")

    # 提取参数值
    converted_args = []
    for arg in call_node.args:
        if isinstance(arg, ast.Str):  # 字符串字面量
            converted_args.append(arg.s)
        elif isinstance(arg, ast.Num):  # 数字字面量
            converted_args.append(arg.n)
        elif isinstance(arg, ast.UnaryOp):  # 一元操作符(如负号)
            if isinstance(arg.op, ast.USub):  # 负号
                operand = arg.operand
                if isinstance(operand, ast.Num):
                    converted_args.append(-operand.n)
                else:
                    raise TypeError(f"Unsupported UnaryOp operand: {type(operand)}")
            else:
                raise TypeError(f"Unsupported UnaryOp operator: {type(arg.op)}")
        elif isinstance(arg, ast.Name):  # 变量名
            converted_args.append(arg.id)
        else:
            raise TypeError(f"Unsupported argument type: {type(arg)}")

    return method_path, converted_args


def extract_attribute_path(attribute_node):
    """
    递归提取嵌套属性路径。
    """
    parts = []
    current_node = attribute_node
    while isinstance(current_node, ast.Attribute):
        parts.append(current_node.attr)
        current_node = current_node.value
    if isinstance(current_node, ast.Name):
        parts.append(current_node.id)
    else:
        raise TypeError(f"Unsupported node type in attribute path: {type(current_node)}")
    return ".".join(reversed(parts))


def extract_right_value(value_node):
    """
    提取右侧值。
    """
    if isinstance(value_node, ast.Call):
        return None  # 如果右侧是函数调用,则返回 None
    elif isinstance(value_node, ast.Str):
        return value_node.s
    elif isinstance(value_node, ast.Num):
        return value_node.n
    elif isinstance(value_node, ast.UnaryOp):  # 处理一元操作符
        if isinstance(value_node.op, ast.USub):  # 负号
            operand = value_node.operand
            if isinstance(operand, ast.Num):
                return -operand.n
            else:
                raise TypeError(f"Unsupported UnaryOp operand: {type(operand)}")
        else:
            raise TypeError(f"Unsupported UnaryOp operator: {type(value_node.op)}")
    else:
        raise TypeError(f"Unsupported value type: {type(value_node)}")

# 测试用例 1:属性赋值 + 数字字面量
input_str = "obj.attr = 10"
print(parse_input(input_str))
# 输出: ('obj.attr', None, [], 10)

# 测试用例 2:属性赋值 + 字符串字面量
input_str = "obj.attr = 'hello'"
print(parse_input(input_str))
# 输出: ('obj.attr', None, [], 'hello')

# 测试用例 3:属性赋值 + 变量
input_str = "obj.attr = var"
print(parse_input(input_str))
# 输出: ('obj.attr', None, [], 'var')

# 测试用例 4:属性赋值 + 函数调用
input_str = "obj.attr = func('param1')"
print(parse_input(input_str))
# 输出: ('obj.attr', 'func', ['param1'], 'FunctionCall')

# 测试用例 5:属性赋值 + 表达式
input_str = "obj.attr = 10 + 5"
print(parse_input(input_str))
# 输出: ('obj.attr', None, [], 'Expression')

树结构FreeCADGui.Selection.addSelection('Cube_Document','Body','BaseShape.Edge7',9.4199,-9,1):

Module(
    body=[
        Expr(
            value=Call(
                func=Attribute(
                    value=Attribute(
                        value=Name(id='FreeCADGui', ctx=Load()),
                        attr='Selection',
                        ctx=Load()),
                    attr='addSelection',
                    ctx=Load()),
                args=[
                    Constant(value='Cube_Document'),
                    Constant(value='Body'),
                    Constant(value='BaseShape.Edge7'),
                    Constant(value=9.4199),
                    UnaryOp(
                        op=USub(),
                        operand=Constant(value=9)),
                    Constant(value=1)],
                keywords=[]))],
    type_ignores=[])
if __name__ == "__main__":
    command = "FreeCADGui.Selection.addSelection('Cube_Document','Body','BaseShape.Edge7',9.4199,-9,1)"
    output_name, method_path, converted_args, right_value = parse_input(command)
    tree = ast.parse(command)
    # 将 AST 转换为字符串
    ast_str = ast.dump(tree, indent=4)

    # 保存到本地文件
    with open("ast_output.txt", "w", encoding="utf-8") as f:
        f.write(ast_str)
    print(f"Output Name: {output_name}")
    print(f"Method Path: {method_path}")
    print(f"Converted Args: {converted_args}")
    print(f"Right Value: {right_value}")

### Python 中将字符串转换为其他类型的函数和方法 #### 字符串转列表 Python 提供了多种方式来实现这一目标。`str.split()` 函数可以按照指定分隔符分割字符串并返回一个由子串组成的列表[^1]。 ```python text = "apple, banana, cherry" result = text.split(", ") print(result) # 输出 ['apple', 'banana', 'cherry'] ``` #### 字符串转集合 当希望去除重复项并对元素执行高效查询时,可考虑把字符串变成集合。这通常通过先拆分成列表再调用 `set()` 构造器完成[^2]。 ```python data = "hello world hello everyone" unique_chars = set(data.replace(" ", "")) print(unique_chars) # 可能输出 {'d', 'e', 'h', 'l', 'o', 'r', 'v', 'y'} ``` #### 字符串转数值型数据 对于简单的整数或浮点数表示形式可以直接应用内置的 `int()` 或者 `float()` 来解析字符串内容。 ```python num_str_int = "42" integer_value = int(num_str_int) print(integer_value) # 输出 42 num_str_float = "-0.789" floating_point_value = float(num_str_float) print(floating_point_value) # 输出 -0.789 ``` #### 使用 eval 执行作为公式的字符串 如果遇到复杂的数学表达式或者其他合法语句,则可以通过 `eval()` 方法安全评估这些表达式[^4]。不过需要注意潜在的安全风险,在实际项目中谨慎使用此特性。 ```python formula = "(3 + 5) * 2 / 4" calculated_result = eval(formula) print(calculated_result) # 输出 4.0 ``` #### 动态创建函数对象 针对更高级的需求比如动态构建函数体的情况,除了常规定义外还可以借助 `exec()` 和闭包技巧或是第三方库如 `ast.literal_eval()` 实现更为灵活的功能[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值