python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python去除Debug代码

Python实现自动去除Debug代码的终极方案

作者:weixin_46244623

这篇文章主要介绍了如何利用Python AST安全移除Debug代码,通过AST解析和节点遍历,可精准删除print、logging.debug、if DEBUG等调试语句,避免正则表达式误删问题,希望对大家有所帮助

在真实项目中,Debug 代码通常包括:

手动删除不现实,正则又极易误伤

AST 是唯一靠谱、可维护的方案

本文教你如何用 Python AST 自动、安全地移除 Debug 代码

一、为什么不能用正则?

错误示例:

# 误删
print = my_print
print("hello")   # 不该删
text = "print(x)"  # 字符串

正则不知道「语义」,而 AST 知道。

二、我们要移除哪些 Debug 代码?

本文支持移除:

类型示例
printprint(x)
logging.debuglogging.debug(x)
logging.infologging.info(x)
logger.debuglogger.debug(x)
if DEBUGif DEBUG: ...

三、核心思路(AST 级别)

关键工具:ast.NodeTransformer

四、完整实现代码(推荐直接用)

Debug 代码移除器

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")

六、进阶场景(非常实用)

1. 只在生产环境移除

if os.getenv("ENV") == "prod":
    code = remove_debug_code(code)

2. 保留 logging.warning / error

只需修改:

LOGGING_METHODS = {"debug", "info"}

3. 移除 assert(生产环境)

def visit_Assert(self, node):
    return None

4. 批量清洗项目代码

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

AST 的优势是:按语义删代码,而不是按字符串

八、适合哪些场景?

到此这篇关于Python实现自动去除Debug代码的终极方案的文章就介绍到这了,更多相关Python去除Debug代码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文