最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python AST 模塊實戰(zhàn)演示

 更新時間:2025年11月21日 17:14:45   作者:煙雨AC  
Python的ast模塊提供了一種處理Python代碼的強大工具,通過解析代碼生成抽象語法樹(AST),可以進行代碼分析、修改和生成,接下來通過本文給大家介紹Python AST 模塊實戰(zhàn)教程,感興趣的朋友跟隨小編一起看看吧

Python 的 ast(Abstract Syntax Tree,抽象語法樹)模塊是一個用于處理 Python 代碼的強大工具。它允許你將代碼轉換為一種結構化的樹形表示,從而可以進行分析、修改甚至生成新的代碼。這對于理解代碼的內部結構、構建開發(fā)工具或進行代碼自動化處理非常有幫助。

?? 什么是抽象語法樹(AST)

在深入了解 ast 模塊之前,我們先簡單理解一下抽象語法樹(AST)的概念。當 Python 解釋器執(zhí)行代碼時,它首先需要理解代碼的結構。這個過程大致是:源代碼 -> 詞法分析(生成令牌流) -> 語法分析(生成 AST) -> 字節(jié)碼 -> 執(zhí)行。AST 就是源代碼抽象語法結構的樹狀表示,它過濾掉了像空格、注釋這類非本質的細節(jié),專注于代碼的邏輯結構。每個節(jié)點代表代碼中的一個結構(例如,一個表達式、一個語句、一個函數(shù)定義等)。

ast 模塊的核心作用就是在這棵“語法樹”上工作,讓你能在代碼被編譯成字節(jié)碼之前,洞察和操作其本質。

??? ast 模塊的核心用法

ast 模塊提供了一系列函數(shù)和類來創(chuàng)建、遍歷和修改 AST。

1. 解析代碼生成 AST

使用 ast.parse() 函數(shù)可以將字符串形式的 Python 代碼解析成一棵 AST 的根節(jié)點(通常是 ast.Module 節(jié)點)。

import ast
code = """
def greet(name):
    print(f"Hello, {name}!")
"""
tree = ast.parse(code)  # 得到 AST

2. 查看 AST 結構

生成 AST 后,可以使用 ast.dump() 函數(shù)將其以文本形式打印出來,以便查看整個樹的結構。

print(ast.dump(tree, indent=4))

這會輸出一個結構化的文本,展示所有的節(jié)點、它們的屬性以及嵌套關系。

3. 遍歷 AST

要分析 AST,你需要遍歷它的節(jié)點。ast 模塊提供了兩種主要方式:

  • 使用 ast.NodeVisitor 類:這是最常用和推薦的方法。你可以創(chuàng)建一個繼承自 ast.NodeVisitor 的類,并為感興趣的節(jié)點類型定義 visit_ 方法(例如 visit_FunctionDef 用于訪問函數(shù)定義節(jié)點)。在方法中,你可以通過 self.generic_visit(node) 來繼續(xù)遍歷當前節(jié)點的子節(jié)點。
class MyVisitor(ast.NodeVisitor):
    def visit_FunctionDef(self, node):
        print(f"Found function: {node.name}")
        self.generic_visit(node)  # 繼續(xù)遍歷子節(jié)點
visitor = MyVisitor()
visitor.visit(tree)
  • 使用 ast.walk() 函數(shù):這個函數(shù)會遞歸地遍歷 AST 中的所有節(jié)點,但不關心節(jié)點的層級關系。它返回一個生成器,適合當你需要找到所有特定類型的節(jié)點時使用。
for node in ast.walk(tree):
    if isinstance(node, ast.FunctionDef):
        print(node.name)

4. 修改 AST

除了分析,你還可以修改 AST。這需要通過繼承 ast.NodeTransformer 類來實現(xiàn)。它的使用方式和 NodeVisitor 類似,但關鍵區(qū)別在于,visit_ 方法需要返回一個節(jié)點。你可以返回:

  • 原節(jié)點:不做任何修改。
  • 新節(jié)點:替換原節(jié)點。
  • None:刪除該節(jié)點。

一個經典的例子是將代碼中的所有加法操作 + 替換為減法操作 -

class AddToSubTransformer(ast.NodeTransformer):
    def visit_BinOp(self, node):
        if isinstance(node.op, ast.Add):
            # 創(chuàng)建一個新的操作符節(jié)點,將加法改為減法
            node.op = ast.Sub()
        return self.generic_visit(node)  # 返回修改后的節(jié)點,并繼續(xù)遍歷其子節(jié)點
transformer = AddToSubTransformer()
new_tree = transformer.visit(tree)

重要提示:在創(chuàng)建新節(jié)點替換舊節(jié)點后,如果新節(jié)點缺少源代碼位置信息(如行號、列偏移量),需要使用 ast.fix_missing_locations() 函數(shù)來修復,否則在編譯時可能會出錯。

5. 將 AST 編譯回代碼

修改完 AST 后,你可以通過內置的 compile() 函數(shù)將其編譯成可執(zhí)行的 Python 字節(jié)碼,然后使用 exec()eval() 來運行它。

# 將修改后的 AST 編譯成代碼對象
code_obj = compile(new_tree, filename='<string>', mode='exec')
# 執(zhí)行代碼對象
exec(code_obj)

此外,從 Python 3.9 開始,標準庫提供了 ast.unparse() 函數(shù),可以直接將 AST 節(jié)點轉換回可讀的 Python 代碼字符串。對于更早的版本,可以使用第三方庫如 astor。

6. 安全地求值表達式

ast 模塊還提供了一個非常實用的函數(shù) ast.literal_eval()。它可以安全地計算一個包含 Python 字面量(如字符串、數(shù)字、元組、列表、字典、布爾值等)的表達式字符串,并返回結果。與內置的 eval() 不同,它不會執(zhí)行任意代碼,因此安全得多,非常適合處理來自不可信來源的數(shù)據(jù)。

safe_result = ast.literal_eval("[1, 2, 3]")  # 結果是列表 [1, 2, 3]

?? 大廠筆試面試如何考察 ast

在大廠的筆試或面試中,對 ast 模塊的考察通常不會要求你死記硬背所有的節(jié)點類型,而是更注重實踐應用能力對 Python 機制的理解深度以及解決實際問題的思路。

常見的考察方向

  • 基礎概念理解
    • 可能會問:AST 在 Python 解釋過程中處于哪個階段?它和字節(jié)碼有什么區(qū)別?
    • 或者:ast.literal_eval()eval() 有什么區(qū)別?為什么前者更安全?
  • 代碼分析與審計
    • 靜態(tài)代碼檢查:讓你編寫一個簡單的檢查器,使用 ast.NodeVisitor 來遍歷代碼,找出潛在問題。例如,檢測是否使用了不安全的函數(shù)(如 evalexec),或者檢查代碼風格(如變量命名規(guī)范)。
    • 代碼復雜度分析:通過分析函數(shù)定義、循環(huán)、條件分支等節(jié)點的數(shù)量和嵌套關系,來估算代碼的復雜度。
  • 代碼轉換與自動化
    • 這是考察的重點和難點。面試官可能會給出一個具體的代碼重構任務,讓你使用 ast.NodeTransformer 來實現(xiàn)自動化。例如:
  • 重命名:將代碼中所有特定變量名或函數(shù)名進行批量替換。
  • 邏輯替換:如前面提到的,將加法操作改為減法。
  • API 升級:假設某個庫的 API 發(fā)生了變化,需要你寫一個工具自動將舊代碼中的函數(shù)調用更新為新形式。
  • 與網(wǎng)絡安全結合
    • 尤其是在安全相關的崗位面試中??赡軙o出一段代碼,要求你分析其中可能存在的安全漏洞(如 SQL 注入、命令注入點),這需要你能夠通過 AST 分析代碼的數(shù)據(jù)流和控制流。

實例分析:面試題模擬

題目:請你使用 ast 模塊,編寫一個簡單的靜態(tài)分析工具,用于檢測一段 Python 代碼中是否使用了 eval() 函數(shù)。如果使用了,則輸出警告信息。

考察點

  • 是否掌握 ast 的基本解析和遍歷操作。
  • 是否熟悉 ast.NodeVisitor 的使用。
  • 能否識別函數(shù)調用節(jié)點(ast.Call)并判斷其函數(shù)名。

參考實現(xiàn)

import ast
code = """
x = 1
result = eval('1 + 1')
print(eval('2+2'))
"""
class EvalDetector(ast.NodeVisitor):
    def visit_Call(self, node):
        # 檢查節(jié)點是否是一個函數(shù)調用,并且函數(shù)名是一個標識符(Name)且id為'eval'
        if isinstance(node.func, ast.Name) and node.func.id == 'eval':
            print(f"Warning: Potential use of eval() found at line {node.lineno}")
        # 繼續(xù)遍歷子節(jié)點,以查找嵌套調用等情況
        self.generic_visit(node)
tree = ast.parse(code)
detector = EvalDetector()
detector.visit(tree)

輸出

Warning: Potential use of eval() found at line 4
Warning: Potential use of eval() found at line 5

這個例子演示了如何使用 ast.NodeVisitor 來訪問代碼中的函數(shù)調用節(jié)點(ast.Call),并根據(jù)條件(函數(shù)名為 eval)進行判斷和輸出。

?? 總結與核心知識點

為了幫助你更好地記憶,我將 ast 模塊的核心知識點整理成了下面的表格:

核心概念/操作關鍵函數(shù)/類說明與用途
解析代碼ast.parse(source)將源代碼字符串解析為 AST 根節(jié)點(ast.Module)。
查看結構ast.dump(node)將 AST 節(jié)點以字符串形式輸出,用于調試。
遍歷 ASTast.NodeVisitor通過繼承此類并定義 visit_XXX 方法來有選擇地訪問節(jié)點。
遍歷 ASTast.walk(node)遞歸遍歷 AST 中的所有節(jié)點,不保留層級信息。
修改 ASTast.NodeTransformer通過繼承此類,在 visit_XXX 方法中返回新節(jié)點來修改 AST。
編譯執(zhí)行compile(tree, ...)將 AST 編譯為可執(zhí)行的代碼對象。
反解析ast.unparse(node) (Python 3.9+)將 AST 節(jié)點轉換回等價的 Python 代碼字符串。
安全求值ast.literal_eval()安全地求值字面量表達式(字符串、列表、數(shù)字等),避免任意代碼執(zhí)行風險。
修復位置ast.fix_missing_locations(node)為新建或修改的節(jié)點補充行號等位置信息,確保能正確編譯。

到此這篇關于Python AST 模塊實戰(zhàn)解析的文章就介紹到這了,更多相關python ast 模塊內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Python實例之wxpython中Frame使用方法

    Python實例之wxpython中Frame使用方法

    本文介紹下wxpython中Frame的用法,不錯的python編程實例,有需要的朋友參考下
    2014-06-06
  • tensorflow mnist 數(shù)據(jù)加載實現(xiàn)并畫圖效果

    tensorflow mnist 數(shù)據(jù)加載實現(xiàn)并畫圖效果

    TensorFlow&#8482; 是一個采用數(shù)據(jù)流圖(data flow graphs),用于數(shù)值計算的開源軟件庫。這篇文章給大家介紹tensorflow mnist 數(shù)據(jù)加載實現(xiàn)并畫圖效果,感興趣的朋友一起看看吧
    2020-02-02
  • Python實現(xiàn)自動化表單填寫功能

    Python實現(xiàn)自動化表單填寫功能

    在Python中,自動化表單填寫可以通過多種庫和工具實現(xiàn),本文將詳細介紹常用的自動化表單處理工具,并對它們進行橫向比較,可根據(jù)需求選擇合適的工具,感興趣的小伙伴跟著小編一起來看看吧
    2025-03-03
  • python實現(xiàn)PDF文檔提取,分割與合并操作

    python實現(xiàn)PDF文檔提取,分割與合并操作

    這篇文章主要為大家詳細介紹了python進行PDF文檔提取,分割與合并等操作的實現(xiàn)方法,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2026-02-02
  • 關于Python Socket編程的要點詳解

    關于Python Socket編程的要點詳解

    Socket是網(wǎng)絡編程的一個抽象概念,通常我們用一個Socket表示“打開了一個網(wǎng)絡鏈接”,而打開一個Socket需要知道目標計算機的IP地址和端口號,再指定協(xié)議類型即可,這篇文章主要給大家介紹了關于Python Socket編程的相關資料,需要的朋友可以參考下
    2021-08-08
  • Python可視化神器pyecharts繪制儀表盤

    Python可視化神器pyecharts繪制儀表盤

    這篇文章主要介紹了Python可視化神器pyecharts繪制儀表盤,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • Python爬蟲中的并發(fā)編程詳解

    Python爬蟲中的并發(fā)編程詳解

    Python爬蟲中的并發(fā)編程是一種優(yōu)化爬取速度、解決阻塞問題、優(yōu)化資源利用的方式。常用的并發(fā)編程模塊包括多線程、多進程、協(xié)程等,通過并發(fā)處理多個任務,可以提高爬取效率,節(jié)省爬蟲資源利用成本。同時,還需注意線程安全、共享資源問題等并發(fā)編程中的常見陷阱
    2023-05-05
  • Python線程之線程安全的隊列Queue

    Python線程之線程安全的隊列Queue

    這篇文章主要介紹了Python線程之線程安全的隊列,是否有一種神器,能解決線程/并發(fā)的問題呢?它就是隊列Queue,下面進入文章和小編學習Queue的相關資料吧
    2022-02-02
  • Python3之字符串比較_重寫cmp函數(shù)方式

    Python3之字符串比較_重寫cmp函數(shù)方式

    這篇文章主要介紹了Python3之字符串比較_重寫cmp函數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Python如何判斷字符串中是否包含特殊字符并替換

    Python如何判斷字符串中是否包含特殊字符并替換

    這篇文章主要為大家詳細介紹了如何使用Python實現(xiàn)判斷字符串中是否包含特殊字符并使用空字符串替換掉,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2025-05-05

最新評論

会同县| 浦城县| 霍山县| 瓮安县| 邮箱| 来凤县| 将乐县| 嘉定区| 贵溪市| 博野县| 遂川县| 河南省| 固始县| 太保市| 修水县| 郑州市| 涡阳县| 秀山| 师宗县| 定安县| 大竹县| 宁明县| 芜湖县| 灯塔市| 镇雄县| 江都市| 法库县| 泸西县| 宜兰市| 永兴县| 鄂托克前旗| 三原县| 郸城县| 分宜县| 应城市| 竹溪县| 金阳县| 乌兰县| 镶黄旗| 武安市| 斗六市|