Python實(shí)現(xiàn)自動(dòng)去除Debug代碼的終極方案
在真實(shí)項(xiàng)目中,Debug 代碼通常包括:
print()logging.debug()logging.info()logger.debug()- 臨時(shí)調(diào)試函數(shù)(如
debug()、pprint()) if DEBUG:塊
手動(dòng)刪除不現(xiàn)實(shí),正則又極易誤傷
AST 是唯一靠譜、可維護(hù)的方案
本文教你如何用 Python AST 自動(dòng)、安全地移除 Debug 代碼。
一、為什么不能用正則?
錯(cuò)誤示例:
# 誤刪
print = my_print
print("hello") # 不該刪
text = "print(x)" # 字符串
正則不知道「語(yǔ)義」,而 AST 知道。
二、我們要移除哪些 Debug 代碼?
本文支持移除:
| 類型 | 示例 |
|---|---|
| print(x) | |
| logging.debug | logging.debug(x) |
| logging.info | logging.info(x) |
| logger.debug | logger.debug(x) |
| if DEBUG | if DEBUG: ... |
三、核心思路(AST 級(jí)別)
- 把代碼解析成 AST
- 遍歷所有語(yǔ)句節(jié)點(diǎn)
- 命中 Debug → 直接刪除節(jié)點(diǎn)
- 重新生成源碼
關(guān)鍵工具:ast.NodeTransformer
四、完整實(shí)現(xiàn)代碼(推薦直接用)
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)
對(duì)外調(diào)用函數(shù)
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)
五、測(cè)試示例
原始代碼
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")
執(zhí)行清理
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)
清理后結(jié)果
import logging
x = 10
print("done")
- Debug 代碼全部移除
- 正常業(yè)務(wù)代碼保留
- 不影響 import / 變量 / 邏輯
六、進(jìn)階場(chǎng)景(非常實(shí)用)
1. 只在生產(chǎn)環(huán)境移除
if os.getenv("ENV") == "prod":
code = remove_debug_code(code)
2. 保留 logging.warning / error
只需修改:
LOGGING_METHODS = {"debug", "info"}
3. 移除 assert(生產(chǎn)環(huán)境)
def visit_Assert(self, node):
return None
4. 批量清洗項(xiàng)目代碼
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 是「終極方案」
| 方案 | 安全性 | 可維護(hù) | 可擴(kuò)展 |
|---|---|---|---|
| 正則 | ? | ? | ? |
| 手動(dòng)刪 | ? | ? | ? |
| AST | ? | ? | ? |
AST 的優(yōu)勢(shì)是:按語(yǔ)義刪代碼,而不是按字符串
八、適合哪些場(chǎng)景?
- 上線前自動(dòng)清理 Debug
- CI/CD 中做代碼凈化
- 訓(xùn)練大模型前清洗代碼語(yǔ)料
- 代碼混淆 / 防逆向
- 企業(yè)級(jí)代碼審計(jì)
到此這篇關(guān)于Python實(shí)現(xiàn)自動(dòng)去除Debug代碼的終極方案的文章就介紹到這了,更多相關(guān)Python去除Debug代碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python實(shí)現(xiàn)HTML轉(zhuǎn)Word的示例代碼
這篇文章主要為大家詳細(xì)介紹了使用Python實(shí)現(xiàn)HTML轉(zhuǎn)Word的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-12-12
Python selenium使用autoIT上傳附件過程詳解
這篇文章主要介紹了Python selenium使用autoIT上傳附件過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Python3的urllib.parse常用函數(shù)小結(jié)(urlencode,quote,quote_plus,unquot
這篇文章主要介紹了Python3的urllib.parse常用函數(shù),結(jié)合實(shí)例形式分析了urlencode,quote,quote_plus,unquote,unquote_plus等函數(shù)的相關(guān)使用技巧,需要的朋友可以參考下2016-09-09
時(shí)間序列分析之ARIMA模型預(yù)測(cè)餐廳銷量
這篇文章主要介紹了時(shí)間序列分析之ARIMA模型預(yù)測(cè)餐廳銷量,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11
深入解析Python中的descriptor描述器的作用及用法
在Python中描述器也被稱為描述符,描述器能夠?qū)崿F(xiàn)對(duì)對(duì)象屬性的訪問控制,下面我們就來深入解析Python中的descriptor描述器的作用及用法2016-06-06
PyCharm2020.1.2社區(qū)版安裝,配置及使用教程詳解(Windows)
這篇文章主要介紹了PyCharm2020.1.2社區(qū)版安裝,配置及使用教程(Windows),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08
使用python爬蟲實(shí)現(xiàn)子域名探測(cè)問題
子域名枚舉是為一個(gè)或多個(gè)域查找子域的過程,它是信息收集階段的重要組成部分,這篇文章主要介紹了使用python實(shí)現(xiàn)子域名探測(cè),需要的朋友可以參考下2022-07-07

