文章目录
- import ast import astor DEBUG_FUNC_NAMES = { “print”, “pprint”, “debug”, } LOGGING_METHODS = { “debug”, “info”, } class RemoveDebugTransformer(ast.NodeTransformer): def visit_Expr(self, node): “”” 处理: – print(…) – logging.debug(…) – logger.debug(…) “”” call = node.value if not isinstance(call, ast.Call): return node func = call.func # print(…) if isinstance(func, ast.Name): if func.id in DEBUG_FUNC_NAMES: return None # logging.debug(…) / logger.debug(…) if isinstance(func, ast.Attribute): if func.attr in LOGGING_METHODS: return None return node def visit_If(self, node): “”” 处理: if DEBUG: … “”” # if DEBUG: if isinstance(node.test, ast.Name) and node.test.id == “DEBUG”: return None return self.generic_visit(node)
- def remove_debug_code(code: str) -> str: tree = ast.parse(code) transformer = RemoveDebugTransformer() tree = transformer.visit(tree) ast.fix_missing_locations(tree) return astor.to_source(tree)
- import logging DEBUG = True print(“hello”) logging.debug(“debug log”) logging.info(“info log”) logger.debug(“logger debug”) x = 10 if DEBUG: print(“only debug”) print(“done”)
- code = “”” import logging DEBUG = True def foo(x): print(“foo x =”, x) logging.debug(“debug foo”) logging.info(“info foo”) if DEBUG: print(“only in debug”) return x * 2 print(“program start”) result = foo(10) print(“result =”, result) “”” new_code = remove_debug_code(code) print(new_code)
- import logging x = 10 print(“done”) Debug 代码全部移除 正常业务代码保留 不影响 import / 变量 / 逻辑
- if os.getenv(“ENV”) == “prod”: code = remove_debug_code(code)
- 只需修改: LOGGING_METHODS = {“debug”, “info”}
- def visit_Assert(self, node): return None
- from pathlib import Path for file in Path(“src”).rglob(“*.py”): code = file.read_text(encoding=”utf-8″) new_code = remove_debug_code(code) file.write_text(new_code, encoding=”utf-8″)
目录
- 一、为什么不能用正则?
- 二、我们要移除哪些 Debug 代码?
- 三、核心思路(AST 级别)
- 四、完整实现代码(推荐直接用)
- Debug 代码移除器
- 对外调用函数
- 五、测试示例
- 原始代码
- 执行清理
- 清理后结果
- 六、进阶场景(非常实用)
- 1. 只在生产环境移除
- 2. 保留 logging.warning / error
- 3. 移除 assert(生产环境)
- 4. 批量清洗项目代码
- 七、为什么 AST 是「终极方案」
- 八、适合哪些场景?
在真实项目中,Debug 代码通常包括:
print()logging.debug()logging.info()logger.debug()- 临时调试函数(如
debug()、pprint()) if DEBUG:块
手动删除不现实,正则又极易误伤
AST 是唯一靠谱、可维护的方案
本文教你如何用 Python AST 自动、安全地移除 Debug 代码。
错误示例:
# 误删
print = my_print
print("hello") # 不该删
text = "print(x)" # 字符串
正则不知道「语义」,而 AST 知道。
本文支持移除:
| 类型 | 示例 |
|---|---|
| print(x) | |
| logging.debug | logging.debug(x) |
| logging.info | logging.info(x) |
| logger.debug | logger.debug(x) |
| if DEBUG | if DEBUG: … |
- 把代码解析成 AST
- 遍历所有语句节点
- 命中 Debug → 直接删除节点
- 重新生成源码
关键工具:ast.NodeTransformer
import ast
import astor
DEBUG_FUNC_NAMES = {
"print",
"pprint",
"debug",
}
LOGGING_METHODS = {
"debug",
"info",
}
class RemoveDebugTransformer(ast.NodeTransformer):
def visit_Expr(self, node):
"""
处理:
- print(...)
- logging.debug(...)
- logger.debug(...)
"""
call = node.value
if not isinstance(call, ast.Call):
return node
func = call.func
# print(...)
if isinstance(func, ast.Name):
if func.id in DEBUG_FUNC_NAMES:
return None
# logging.debug(...) / logger.debug(...)
if isinstance(func, ast.Attribute):
if func.attr in LOGGING_METHODS:
return None
return node
def visit_If(self, node):
"""
处理:
if DEBUG:
...
"""
# if DEBUG:
if isinstance(node.test, ast.Name) and node.test.id == "DEBUG":
return None
return self.generic_visit(node)
def remove_debug_code(code: str) -> str:
tree = ast.parse(code)
transformer = RemoveDebugTransformer()
tree = transformer.visit(tree)
ast.fix_missing_locations(tree)
return astor.to_source(tree)
import logging
DEBUG = True
print("hello")
logging.debug("debug log")
logging.info("info log")
logger.debug("logger debug")
x = 10
if DEBUG:
print("only debug")
print("done")
code = """
import logging
DEBUG = True
def foo(x):
print("foo x =", x)
logging.debug("debug foo")
logging.info("info foo")
if DEBUG:
print("only in debug")
return x * 2
print("program start")
result = foo(10)
print("result =", result)
"""
new_code = remove_debug_code(code)
print(new_code)
import logging
x = 10
print("done")
- Debug 代码全部移除
- 正常业务代码保留
- 不影响 import / 变量 / 逻辑
if os.getenv("ENV") == "prod":
code = remove_debug_code(code)
只需修改:
LOGGING_METHODS = {"debug", "info"}
def visit_Assert(self, node):
return None
from pathlib import Path
for file in Path("src").rglob("*.py"):
code = file.read_text(encoding="utf-8")
new_code = remove_debug_code(code)
file.write_text(new_code, encoding="utf-8")
| 方案 | 安全性 | 可维护 | 可扩展 |
|---|---|---|---|
| 正则 | ❌ | ❌ | ❌ |
| 手动删 | ❌ | ❌ | ❌ |
| AST | ✅ | ✅ | ✅ |
AST 的优势是:按语义删代码,而不是按字符串
- 上线前自动清理 Debug
- CI/CD 中做代码净化
- 训练大模型前清洗代码语料
- 代码混淆 / 防逆向
- 企业级代码审计
到此这篇关于Python实现自动去除Debug代码的终极方案的文章就介绍到这了,更多相关Python去除Debug代码内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Python代码调试Debug的实用技巧分享
- Python内置debug库pdb用法示例详解
- pycharm的debug调试以及异常,Python中错误的处理过程
- Python中使用绝佳的八个Debug 工具
- python进行debug操作实战训练
- Python必备技能之debug调试教程详解