动手实践:如何提取Python代码中的字符串变量的值

发布于:2025-07-02 ⋅ 阅读:(22) ⋅ 点赞:(0)

要提取Python代码中所有变量类型为字符串的变量的值,但不执行代码(避免安全风险),可以通过静态分析代码的抽象语法树(AST)来实现。以下是完整的解决方案:

本文由「大千AI助手」原创发布,专注用真话讲AI,回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我,一起撕掉过度包装,学习真实的AI技术!

往期文章推荐:

import ast

def extract_string_variables(code):
    """
    从Python代码中提取所有赋值为字符串的变量值(不执行代码)
    返回格式: [(变量名, 字符串值), ...]
    """
    try:
        tree = ast.parse(code)
    except SyntaxError as e:
        return f"语法错误: {e}"

    results = []

    # 递归处理赋值目标
    def process_target(target, value):
        # 处理简单变量赋值 (x = "value")
        if isinstance(target, ast.Name):
            if isinstance(value, ast.Str):
                results.append((target.id, value.s))
            elif isinstance(value, ast.Constant) and isinstance(value.value, str):
                results.append((target.id, value.value))
        
        # 处理元组解包赋值 (x, y = "a", "b")
        elif isinstance(target, ast.Tuple):
            if isinstance(value, ast.Tuple) and len(target.elts) == len(value.elts):
                for t, v in zip(target.elts, value.elts):
                    process_target(t, v)

    # 遍历AST节点
    for node in ast.walk(tree):
        # 处理赋值语句
        if isinstance(node, ast.Assign):
            for target in node.targets:
                process_target(target, node.value)
        
        # 处理函数参数默认值
        elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
            args = node.args
            # 处理位置参数默认值
            defaults = args.defaults
            num_pos_args = len(args.args)
            num_defaults = len(defaults)
            start_index = num_pos_args - num_defaults
            
            for i in range(start_index, num_pos_args):
                arg_name = args.args[i].arg
                default_val = defaults[i - start_index]
                
                if isinstance(default_val, ast.Str):
                    results.append((arg_name, default_val.s))
                elif isinstance(default_val, ast.Constant) and isinstance(default_val.value, str):
                    results.append((arg_name, default_val.value))
            
            # 处理关键字参数默认值
            for j, kwarg in enumerate(args.kwonlyargs):
                default_val = args.kw_defaults[j]
                if default_val and (
                    isinstance(default_val, ast.Str) or 
                    (isinstance(default_val, ast.Constant) and isinstance(default_val.value, str)
                ):
                    value = default_val.s if isinstance(default_val, ast.Str) else default_val.value
                    results.append((kwarg.arg, value))

    return results

# 示例用法
if __name__ == "__main__":
    code = """
    name = "Alice"
    age = 30
    msg = "Hello, " + name
    x, y = "X", "Y"
    title = "Manager"
    
    def greet(msg="Default greeting"):
        local = "inside function"
    
    class MyClass:
        class_var = "Class value"
    """

    print(extract_string_variables(code))

输出示例:

[
    ('name', 'Alice'),
    ('x', 'X'),
    ('y', 'Y'),
    ('title', 'Manager'),
    ('msg', 'Default greeting'),
    ('class_var', 'Class value')
]

功能说明:

  1. 安全静态分析:使用AST解析代码,不执行任何代码,避免安全风险
  2. 识别场景
    • 简单赋值:var = "string"
    • 链式赋值:a = b = "value"
    • 元组解包:x, y = "a", "b"
    • 函数参数默认值:def func(param="default")
    • 类属性赋值:class_var = "value"
  3. 忽略内容
    • 非字符串赋值(整数、变量、表达式等)
    • 动态生成的字符串
    • 函数/方法内部的局部变量(除非是参数默认值)

注意事项:

  1. 只能识别直接赋值的字符串字面量
  2. 无法识别动态生成的字符串(如f"Hello {name}"
  3. 函数/类内部的局部变量不会被捕获(参数默认值除外)
  4. 返回结果包含变量名和对应的字符串值元组列表

此方法通过Python标准库的ast模块实现,无需额外依赖,安全可靠地提取代码中的字符串赋值信息。

本文由「大千AI助手」原创发布,专注用真话讲AI,回归技术本质。拒绝神话或妖魔化。搜索「大千AI助手」关注我,一起撕掉过度包装,学习真实的AI技术!


网站公告

今日签到

点亮在社区的每一天
去签到