Python进阶之-ast使用详解

✨前言:

🌟什么是ast?

ast模块在Python中用于将源码转换成抽象语法树(Abstract Syntax Trees,AST)。通过AST,我们可以读取、修改、分析Python代码。本质上,它将源码转化为树形结构,节点代表语法构造,如表达式、语句等。这对于编写代码分析、优化工具或自动代码生成等任务非常有用。
抽象语法树(AST)组成部分
Expression: 在Python的AST中,Expression节点表示一个表达式。这里,它是整个AST的根节点。Expression节点有一个body属性,用于存储表达式的主体。body=BinOp(…): body属性包含一个BinOp节点,表示一个二元操作(binary operation)。二元操作就是涉及两个操作数的运算,比如加法、减法等。left=Constant(value=2): 在BinOp节点中,left属性表示左侧的操作数。

🌟基本使用

首先,使用import ast命令导入ast模块。

⭐️例1:解析表达式
#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/5/4
# @Author  : Summer
# @File    : test
# @describe:
"""
import ast

expression = "(1 + 2) * 3"
tree = ast.parse(expression, mode='eval')

print(ast.dump(tree, indent=4))
# Expression(body=BinOp(left=BinOp(left=Constant(value=1, kind=None), op=Add(),
# right=Constant(value=2, kind=None)), op=Mult(), right=Constant(value=3, kind=None)))

该示例中,先通过ast.parse函数解析字符串表达式。mode='eval’表示这是一个表达式。然后利用ast.dump函数打印出该表达式的树形结构,indent=4参数使输出更加易于阅读。

Expression:表示这是一个表达式节点。在AST种,Expression用于包装一个表达式,这里它是根节点。
body:这是Expression节点的主体,它包含了真正的运算逻辑。
BinOp:代表二元操作的节点,即涉及两个操作数的运算。在这个例子中,有两层BinOp。
第一层BinOp(外层)代表乘法操作(Mult()),它的两个操作数分别是: left=BinOp()
(内层):这个代表加法操作(Add())。具体包含: left=Constant(value=1,
kind=None):这是一个常量节点,表示整数1。 right=Constant(value=2,
kind=None):这也是一个常量节点,表示整数2。 这表明内层BinOp表示的表达式是1 + 2。 第一层BinOp的另一个操作数是:
right=Constant(value=3, kind=None):这是一个表示整数3的常量节点。
op:这个属性表示操作类型,Add()是加法操作,Mult()是乘法操作。 因此,这整个Expression节点表示的表达式是:(1 +
2) * 3。 kind=None:在Constant节点中,kind属性表示常量的字面种类。

⚠️注意:indent=4参数是python3.9版本之后引入的,需要注意自己的python版本。

⭐️例2:遍历AST节点

要访问AST的每个节点,最直接的方法是使用ast.NodeVisitor类。下面我们实现一个简单的访问者,计算AST树中出现的所有Num节点的总和:

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/5/4
# @Author  : Summer
# @File    : test
# @describe:
"""
import ast


class SumNumbers(ast.NodeVisitor):
    def __init__(self):
        self.total = 0

    def visit_Num(self, node):
        self.total += node.n
        self.generic_visit(node)

expression = "1 + 2 + (3 * 4)"
tree = ast.parse(expression, mode='eval')
visitor = SumNumbers()
visitor.visit(tree)

print(visitor.total)  # 10

上例中,SumNumbers类继承自ast.NodeVisitor,通过定义visit_方法来处理特定类型的节点。这里,我们处理Num节点,即数值。
👉为什么输出是10?
对于表达式 “1 + 2 + (3 * 4)”,简化的AST遍历如下:
数值 1(Constant节点)
数值 2(Constant节点)
数值 3(Constant节点)
数值 4(Constant节点)
根据此逻辑,总结如下:

1出现1次。
2出现1次。
3出现1次(作为乘法操作的一部分)。
4出现1次(作为乘法操作的一部分)。
累加这些数值得到的total是10,实际上,AST保持了源码的结构,对于(3 * 4),它会以3和4两个独立的Constant节点存在于树中,同时由BinOp节点表示这个乘法操作。

⭐️例3:修改AST节点

若要修改AST,可以使用ast.NodeTransformer类。以下例子把所有的数字乘以2:

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/5/4
# @Author  : Summer
# @File    : test
# @describe:
"""
import ast


class DoubleNumbers(ast.NodeTransformer):
    def visit_Num(self, node):
        return ast.copy_location(ast.Num(n=node.n * 2), node)

expression = "1 + 2"
tree = ast.parse(expression, mode='eval')
transformer = DoubleNumbers()
new_tree = transformer.visit(tree)

print(ast.dump(new_tree)) 

这个例子通过继承ast.NodeTransformer并重写visit_Num方法,来修改数值节点。ast.copy_location帮助保持原节点的源代码位置信息。

⭐️ast.Attribute

ast.Attribute 类型在 Python 的抽象语法树(AST)中用于表示对属性的访问,例如在访问对象的属性或方法时。举一个简单的例子,当你有一个像 object.attribute 这样的代码时,可以通过 ast 模块来解析和理解这种结构。

先看一个具体的代码示例,然后解析它:

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/5/4
# @Author  : Summer
# @File    : test
# @describe:
"""

import ast

# 假设我们有如下代码,我们想要解析它
code = """
class MyClass:
    def method(self):
        pass

obj = MyClass()
obj.method()
"""

# 使用 ast.parse 将代码字符串解析为 AST
parsed_code = ast.parse(code)


# 定义一个访问者类,该类继承自 ast.NodeVisitor
class MyVisitor(ast.NodeVisitor):
    def visit_Attribute(self, node):
        print(f"Found an attribute access: {node.attr}")
        self.generic_visit(node)  # 继续访问节点的子节点


# 实例化我们的访问者,并访问解析得到的 AST
visitor = MyVisitor()
visitor.visit(parsed_code)  # Found an attribute access: method

在这个例子中,我们定义了一个名为 MyClass 的类和一个该类的实例 obj。随后,我们通过 obj.method() 调用类的一个方法。我们的目标是通过访问 AST 来找到这种对属性(在这个案例中是方法)的访问。这里,当实例化 MyVisitor 类并调用它的 visit 方法时,它会遍历整个 AST。每当遇到 ast.Attribute 类型的节点时,visit_Attribute 方法将被调用,打印出我们正在访问的属性的名字。输出结果为 Found an attribute access: method 这表明,我们成功地识别了代码中对属性(或方法)method 的访问。

⭐️ ast.Constant

ast.Constant 是 Python 抽象语法树(AST)中表示字面量值的节点类型。这包括数值字面量(如整数、浮点数)、字符串字面量、布尔值(True 和 False)以及 None。下面通过一个例子介绍如何使用 ast 模块来解析这些常量,并展示如何访问它们。
假设我们有一段包含字面量值的 Python 代码,我们希望解析这段代码并识别出所有的常量值。

#!/usr/bin/env python
# coding=utf-8
"""
# @Time    : 2024/5/4
# @Author  : Summer
# @File    : test
# @describe:
"""

import ast

# 定义一个包含各种常量的代码字符串
code = """
x = 10
y = 3.14
name = "Python"
flag = True
nothing = None
"""

# 使用 ast.parse 将代码字符串解析为 AST
parsed_code = ast.parse(code)

# 定义一个访问者类,该类继承自 ast.NodeVisitor
class FindConstants(ast.NodeVisitor):
    def visit_Constant(self, node):
        print(f"Found a constant: {node.value}")
        self.generic_visit(node)  # 继续访问节点的子节点

# 实例化我们的访问者,并访问解析得到的 AST
finder = FindConstants()
finder.visit(parsed_code)

在这个例子中,我们首先定义了一个包含不同类型常量的代码字符串,随后通过 ast.parse 函数将其解析为 AST。然后,我们定义了一个 FindConstants 类,它是 ast.NodeVisitor 的子类,用于遍历 AST。对于每一个遇到的 ast.Constant 节点,我们将其值打印出来。
输出:

Found a constant: 10
Found a constant: 3.14
Found a constant: Python
Found a constant: True
Found a constant: None

这表示我们成功识别并访问了代码中的所有常量。通过这种方式,使用 ast 模块可以使我们能够对 Python 代码进行静态分析,例如识别代码中的硬编码值、分析代码的结构等。ast.NodeVisitor 提供了一种强大的机制,允许我们通过重写其方法来自定义对不同类型节点的访问行为,从而实现对 AST 的遍历和操作。

🌟ast常见用途

静态代码分析:分析代码结构,检查编码规范或查找潜在的bug。
代码优化:修改AST,进行诸如常量传播、死码删除等简单优化。
代码生成:根据特定的逻辑生成新的Python代码片段。
注意事项
使用ast时要小心执行任意的Python代码,特别是使用ast.literal_eval时,因为它比eval安全,但仍需谨慎对待输入源。
修改AST需要理解Python的语法结构,否则可能产生语法错误的代码。
ast模块是Python语言强大的特性之一。它不仅允许代码自省和动态修改,还可以用于构建复杂的编程工具和框架。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607834.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【混合轻量化】MobileNetV4 - Universal Models for the Mobile Ecosystem

MobileNetV4 - Universal Models for the Mobile Ecosystem MobileNetV4 - 移动生态系统的通用模型 论文链接:http://arxiv.org/abs/2404.10518 代码链接:https://github.com/tensorflow/models/blob/master/official/vision/modeling/backbones/mobil…

LoRA的原理简介

在文章开始前先澄清一个概念,需要区分形近的单词"LoRa"(long range),这是一项通信技术。熟悉物联网行业的朋友相对会比较熟悉LoRa这项技术,因为有些设备比如电梯的控制就使用了这个技术进行本地数据和命令的…

【Java】还不会数组?一文万字全搞定

前言:前面两章我们详细讲解了Java基本程序设计结构中的基本知识,,包括:一个简单的Java应用,注释,数据类型,变量与常量,运算符,字符串,输入输出,控…

冯喜运:5.10黄金反弹受阻,原油EIA库存激增引发市场情绪

【黄金消息面分析】:据最新市场数据显示,现货黄金在周四欧市早盘经历了显著下滑,价格一度跌破2310美元/盎司的关口,日内高点回落达10美元,截至发稿,黄金小幅反弹,交投于2312美元/盎司附近。此番…

网络新手如何上手水牛社软件?我的建议与看法

水牛社是一款专为电脑用户设计的软件,拥有明确的著作权,其核心功能在于发布和整合各类网络活动任务资源、教程等,内容多元且不设固定分类。其靠谱程度取决于你对软件的了解程度和个人需求的适配性。 软件内部包含五个主要栏目,大…

mysql: docker 异常 - mbind: Operation not permitted

mbind: Operation not permitted 前言:正文:结论 : 前言: 用数据库处理平台问题今天报错,mbind: Operation not permitted。 mbind 不允许操作,一头雾水这是什么意思。 网上找了很多资料大概意思是: 这个错…

SpringBoot中使用RocketMQ实现事务消息来保证分布式事务的一致性(有代码)

前言 分布式事务是分布式系统中非常常见的问题。是非常必要钱常见的。实现的方式也是多种多样。今天这个视频主要来分享一下RocketMQ实现事务消息来保证分布式事务的一致性。不知道大家使用过这种方式没有。这种分布式事务的原理其实和本地消息表一样。 本地消息表实现分布式…

1.基于python的单细胞数据预处理-质量控制

目录 质量控制过滤低质量细胞的指南双细胞过滤手动过滤低质量读数细胞自动过滤低质量读数细胞环境RNA校正 参考: [1] https://github.com/Starlitnightly/single_cell_tutorial [2] https://github.com/theislab/single-cell-best-practices 质量控制 原始的单细胞…

模拟实现链表的功能

1.什么是链表? 链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 。 实际中链表的结构非常多样,以下情况组合起来就有8种链表结构: 单向或者双向 带头或者不带头 …

猫头虎分享已解决Bug || Node.js安装失败Error: unable to connect to https://nodejs.org/猫头虎

猫头虎分享已解决Bug || Node.js安装失败Error: unable to connect to https://nodejs.org/猫头虎 博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — …

活动回顾 |观测云 AI Agent 探索实践

亚马逊云科技“构建全球化软件和互联网新生态——ISV 行业”论坛上,观测云产品架构师刘锐发表了题为“AI Agent 可观测性探索与实践”的主题演讲,不仅展示了观测云在人工智能领域的前沿技术,更强调了在日益复杂的系统环境中,实现有…

autoware.universe 使用之Rosbag replay simulation放包仿真

本文将按照官方文档,通过播放rosbag录制包进行可视化模拟,中间也报了很多错误,特此记录下来,以免后续踩坑。 电脑配置如下:    ubuntu20.04    cuda: cuda-11.6    nvidia-driver 535    ros2: foxy 关于auto…

「MDN web 入门」学习笔记

目录 写在前面 1. MDN 简介 1.1 MDN 的主要特点 1.2 MDN 的主要功能 1.3 MDN 网页开发的指南 2. 安装基础软件 2.1 专业人士工具 2.2 初学者基本工具 3. 设计网站外观 3.1 计划 3.2 绘制草图 3.3 选定素材 3.4 文本 3.5 主题颜色 3.6 图像 3.7 字体 4. 处理文…

Redis(无中心化集群搭建)

文章目录 1.无中心化集群1.基本介绍2.集群说明 2.基本环境搭建1.部署规划(6台服务器)2.首先删除上次的rdb和aof文件(对之前的三台服务器都操作)1.首先分别登录命令行,关闭redis2.清除/root/下的rdb和aof文件3.把上次的…

认识卷积神经网络

我们现在开始了解卷积神经网络,卷积神经网络是深度学习在计算机视觉领域的突破性成果,在计算机视觉领域,往往我们输入的图像都很大,使用全连接网络的话,计算的代价较高,图像也很难保留原有的特征&#xff0…

oracle 数据库找到UDUMP的文件名称

oracle 数据库找到UDUMP的文件名称 select p.value||\||i.instance_name||_ora_||spid||.trc as "trace_file_name" from v$parameter p ,v$process pro, v$session s, (select sid from v$mystat where rownum1) m, v$instance i where lower(p.name)user_dump_…

Java_File

介绍: File对象表示路径,可以是文件,也可以是文件夹。这个路径可以是存在的,也可以是不存在的,带盘符的路径是绝对路径,不带盘符的路径是相对路径,相对路径默认到当前项目下去找 构造方法&…

英伟达推出视觉语言模型:VILA

NVIDIA和MIT的研究人员推出了一种新的视觉语言模型(VLM)预训练框架,名为VILA。这个框架旨在通过有效的嵌入对齐和动态神经网络架构,改进语言模型的视觉和文本的学习能力。VILA通过在大规模数据集如Coy0-700m上进行预训练,采用基于LLaVA模型的…

三.Django--ORM(操作数据库)

目录 1 什么是ORM 1.1 ORM优势 1.2ORM 劣势 1.3 ORM与数据库的关系 2 ORM 2.1 作用 2.2 连接数据库 2.3 表操作--设置字段 2.4 数据库的迁移 写路由增删改查操作 项目里的urls.py: app里的views.py: 注意点: 1 什么是ORM ORM中文---对象-关系映射 在MTV,MVC设计…

2024面试自动化测试面试题【含答案】

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…
最新文章