如何调整Python代码格式将单条语句转为单行以提取Django ORM查询?
处理多行Python语句提取Django ORM查询的方案
方案1:使用AST(抽象语法树)解析(推荐,准确率最高)
这是最可靠的实现方式,无需手动处理换行、括号匹配等边界逻辑:
- 遍历项目内所有
.py文件,读取完整的文件代码内容 - 调用
ast.parse()将代码解析为抽象语法树,AST会自动将跨多行的完整语句识别为单个节点,不受换行格式影响 - 遍历所有AST节点,筛选出调用方法属于Django ORM查询范畴的节点(常见方法包括
filter、exclude、annotate、aggregate、get、order_by等) - Python 3.9+可直接用
ast.unparse()将匹配节点转为代码字符串,低版本可使用第三方库astor的to_source方法,再把得到的代码按空格拆分后重新拼接,即可得到无多余换行的单行语句 - 直接将处理后的单行语句写入CSV即可
示例代码片段:
import ast import csv import os # 可根据项目需要扩充匹配的ORM方法名 ORM_QUERY_METHODS = {'filter', 'exclude', 'annotate', 'aggregate', 'get', 'all', 'order_by', 'values', 'values_list'} def extract_orm_queries(project_dir, output_csv_path): with open(output_csv_path, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['file_path', 'line_number', 'query_code']) for root, _, files in os.walk(project_dir): for file in files: if not file.endswith('.py'): continue file_path = os.path.join(root, file) with open(file_path, 'r', encoding='utf-8') as code_f: try: code_content = code_f.read() tree = ast.parse(code_content) except SyntaxError: # 跳过存在语法错误的文件 continue for node in ast.walk(tree): if isinstance(node, ast.Call) and hasattr(node.func, 'attr') and node.func.attr in ORM_QUERY_METHODS: single_line_code = ' '.join(ast.unparse(node).split()) writer.writerow([file_path, node.lineno, single_line_code])
方案2:文本逐行处理(适合不想引入AST逻辑的轻量场景)
如果仅需要简单处理,不想涉及语法解析,可以通过括号计数实现续行判断:
- 逐行读取代码时维护括号计数器,每遇到
(、[、{则+1,遇到)、]、}则-1 - 若括号计数器大于0,说明当前语句未结束,将当前行内容拼接到上一行的缓存中
- 若括号计数器等于0,说明当前语句结束,将缓存内容去除多余换行、空白后整理为单行,清空缓存等待下一条语句
- 额外处理两个边界:行尾为反斜杠
\时直接续行;跳过三引号包裹的字符串内容,不对字符串内的括号计数 - 该方案可覆盖绝大多数常规多行ORM查询场景,仅在存在嵌套三引号、复杂字符串拼接等极端情况可能出现误差
内容的提问来源于stack exchange,提问作者Mayank Bhatt
相关产品推荐
相关产品推荐

