Python的exec

2023-11-14

目录

 

exec()简单使用

动态执行简单的字符串代码

动态执行较复杂的代码

执行文件中的Python代码

在exec中传参

使用中遇到的问题

参考


exec()简单使用

个人比较喜欢用Python里面的exec(),可以用来动态执行字符串代码,在for循环里面能快速执行大量类似于list1= 1,list2=2,list3=3..这样的语句,使代码显得更加简洁。

首先简单说一说exec(),exec()是一个十分有趣且实用的内置函数,不同于eval()函数只能执行计算数学表达式的结果的功能,exec()能够动态地执行复杂的Python代码,功能强大但是也有不少小地方容易踩坑的,坑好出但是不太好理解,光影并存吧。

动态执行简单的字符串代码

动态执行较复杂的代码

func = "def fact(n):\n\treturn 1 if n==1 else n*fact(n-1)"
exec(func)
a = fact(5)
print(a)

执行文件中的Python代码

在eg.txt中存储我们想放的Python代码

def fact(n):
    if n==1:
        return 1
    else:
        return n*fact(n-1)
t = fact(6)
print(t)

在exec中传参

x = 10
expr = """
z = 30
sum = x + y + z
print(sum)
"""

def func():
    y = 20
    exec(expr)
    exec(expr, {'x': 1, 'y': 2})
    exec(expr, {'x': 1, 'y': 2}, {'y': 3, 'z': 4})

func()

使用中遇到的问题

今天在使用时遇到了一些问题简单记录一下。

def main():
    file_list = [2014, 2045, 2065, 2070, 2080, 2110, 2123, 2133]
    generate_outliers_analysis_log(file_list, "log/outliers.log")

    for file in file_list:
        csv_df = csv_file_to_df(r"D:/FTPD/newEnv/" + str(file) + ".csv")
        port_suffix = [33, 35, 36, 37, 39, 40]
        loc = locals()
        for suffix in port_suffix:
            # 通过执行字符串代码来避免反复执行相同语句
            exec("sorted_df_%s =  get_sorted_port_df(csv_df, '25GE1/0/%s')" % (str(suffix), str(suffix)))
        sorted_df_33, sorted_df_35, sorted_df_36 = loc["sorted_df_33"], loc["sorted_df_35"], loc["sorted_df_36"]
        sorted_df_37, sorted_df_39, sorted_df_40 = loc["sorted_df_37"], loc["sorted_df_39"], loc["sorted_df_40"]
        sorted_df_list = [sorted_df_33, sorted_df_35, sorted_df_36, sorted_df_37, sorted_df_39, sorted_df_40]
        name_list = ["25GE1/0/33", "25GE1/0/35", "25GE1/0/36", "25GE1/0/37", "25GE1/0/39", "25GE1/0/40"]
        save_port_figure_and_excel(range(1, 7), sorted_df_list, name_list, str(file), 'port_csv/' + str(file) + '.xlsx')

这一行代码在运行时遇到了报错:

sorted_df_33, sorted_df_35, sorted_df_36 = loc["sorted_df_33"], loc["sorted_df_35"], loc["sorted_df_36"]

报错信息如下:

sorted_df_33, sorted_df_35, sorted_df_36 = loc["sorted_df_33"], loc["sorted_df_35"], loc["sorted_df_36"]
KeyError: 'sorted_df_33'。

一看就让人觉得奇怪,为了避免出现KeyError的问题,exec常常和locals()连用。

首先,关于locals,个人认为值得注意的有四点:

  • 1.locals() 字典是局部命名空间的代理,它会采集局部作用域的变量,代码运行期若动态修改局部变量,只会影响该字典,并不会影响真正的局部作用域的变量。
  • 2.当再次调用 locals() 时(即两次调用locals()时),由于重新采集,则动态(exec())修改的内容会被丢弃,locals()会被刷新为不包含之前exec()执行后的kv对的字典。
  • 3.运行期的局部命名空间不可改变,这意味着 exec() 函数中的变量赋值不会对它产生影响,但 locals() 字典是可变的,会受到 exec() 函数的影响
  • 4.locals()字典既然是局部命名空间(字典)的代理,会包含在当前局部作用域中的所有的局部变量,那么在把locals()的结果赋给一个变量时,就会产生循环引用

第4点什么意思呢,举个简单的例子

def test():
    a = 13
    loc = locals()
    exec('b = a + 1')
    b = loc['b']
    print(b)

在上面这一小段代码中,当执行到loc = locals()这一行时,loc这一个字典会有一个key为‘loc’,值为loc这个字典本身的键值对。

而且这个loc是一个循环引用,看一下下面的debug图就知道了。为什么呢,因为locals()会包含在当前局部作用域中的所有的局部变量。由于loc本身也是一个局部变量,所以就造成了循环引用

exec的常见陷阱

https://segmentfault.com/a/1190000019217209

对遇到的问题的分析

看完上面的链接文章,个人觉得已经讲解的很透彻了。回头来简单看下,就是说对于下面的例一,会报一个KeyError,对于下面的例二,则不会报错。这与locals()的调用位置有关系,locals()是局部变量的字典的copy,运行期的局部命名空间(局部变量字典)不可改变,这意味着 exec() 函数中的变量赋值不会对它产生影响,但 locals() 字典是可变的,会受到 exec() 函数的影响。意味着我们如果希望在后面获取exec中动态执行的值来赋给新的变量的话,需要在exec之前调用locals(),否则无法获取

好,在此基础上我们来回顾今天遇到的问题,首先简化出现如上问题的业务代码为下图示例3的exec+locals+占位符的example3的使用方式,然后利用example4的方式来做一个简单的验证。咦,这里就出现了一个有趣的问题,按理来说,在example3()函数中,第2行定义了loc,这里的loc在第3行第4行执行完成后是会被exec修改的,即loc中是肯定有“a0”"a1"“a2”“a3”"a4"5个key的,这个在example4中也得到了验证,即只要不用原本的变量名就可以获取。我也不太明白为什么会产生这样的报错,也许这是exec和占位符的设计问题吧,由此也可以得出一个结论,在代码中要获取exec动态执行的变量值,建议还是不要重名,避免定位这些细小琐碎的问题花费较多的时间。:

参考

https://segmentfault.com/a/1190000014581721

https://segmentfault.com/a/1190000019217209

https://python3-cookbook.readthedocs.io/zh_CN/latest/c09/p23_executing_code_with_local_side_effects.html

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python的exec 的相关文章

  • 错误:process_executor.py:702: ... 当一些作业被分配给执行器时,工作人员停止了。这可能是由于工作超时太短造成的

    根据主题中的错误 修复方法是什么 环境 Python 3 9 或 3 10 Windows 10 x64 使用时出现错误joblib https joblib readthedocs io en latest 对于并行处理 result c
  • 如何避免使用 python 处理空的标准输入?

    The sys stdin readline 返回之前等待 EOF 或新行 所以如果我有控制台输入 readline 等待用户输入 相反 我想打印帮助并在没有需要处理的情况下退出并显示错误 而不是等待用户输入 原因 我正在寻找一个Pytho
  • 从文本文件中删除特定字符

    我对 Python 和编码都很陌生 我当时正在做一个小项目 但遇到了一个问题 44 1 6 23 2 7 49 2 3 53 2 1 68 1 6 71 2 7 我只需要从每行中删除第三个和第六个字符 或者更具体地说 从整个文件中删除 字符
  • Mypy 无法从文字列表推断项目的类型

    我有一个变量x和一个文字列表 例如 0 1 2 我想转换x这些文字之一 如果x在列表中 我将其退回 否则我返回一个后备值 from typing import Literal Set Foo Literal 0 1 2 foos Set F
  • 创建上下文后将 jar 文件添加到 pyspark

    我正在笔记本上使用 pyspark 并且不处理 SparkSession 的创建 我需要加载一个包含一些我想在处理 rdd 时使用的函数的 jar 您可以使用 jars 轻松完成此操作 但在我的特定情况下我无法做到这一点 有没有办法访问sp
  • 使用 Paramiko 进行 DSA 密钥转发?

    我正在使用 Paramiko 在远程服务器上执行 bash 脚本 在其中一些脚本中 存在与其他服务器的 ssh 连接 如果我只使用 bash 不使用 Python 我的 DSA 密钥将被第一个远程服务器上的 bash 脚本转发并使用 以连接
  • 协程从未被等待

    我正在使用一个简单的上下文管理器 其中包含一个异步循环 class Runner def init self self loop asyncio get event loop def enter self return self def e
  • 在 python pandas 中,如何保存“网格图”?

    我对 pandas 绘图工具很陌生 在文档中 以下命令非常方便 myplot rts ret hist bins 50 by rts primary mic 然而 当我尝试从图中获取图形参考并保存它时 问题就出现了 myfigure myp
  • Arcpy 模数在 Pycharm 中不显示

    如何将 Arcpy 集成到 Pycharm 中 我尝试通过导入模块但它没有显示 我确实知道该模块仅适用于 2 x python arcpy 在 PyPi Python 包索引 上不可用 因此无法通过 pip 安装 要使用 arcpy 您需要
  • AttributeError:“模块”对象没有属性[重复]

    这个问题在这里已经有答案了 我有两个 python 模块 a py import b def hello print hello print a py print hello print b hi b py import a def hi
  • Python将文本文件解析为嵌套字典

    考虑以下数据结构 HEADER1 key value key value HEADER2 key value key value HEADER3 key value HEADER4 key value key value 原始数据中没有缩进
  • Plotly:如何检查基本图形结构(版本 4)

    对于旧版本的plotly 例如在 Jupyterlab 中 您可以简单地运行figure像这样检查你的图形的基础知识 Ouput data marker color red size 10 symbol 104 mode markers l
  • 从 Flask 运行 NPM 构建

    我有一个 React 前端 我想在与我的 python 后端 API 相同的源上提供服务 我正在尝试使用 Flask 来实现此目的 但我遇到了 Flask 找不到我的静态文件的问题 我的前端构建是用生成的npm run build in s
  • 如何查找或安装适用于 Python 的主题 tkinter ttk

    过去 3 个月我一直在制作一个机器人 仅用代码就可以完美运行 现在我的下一个目标是为它制作一个 GUI 但是我发现了一些障碍 主要的一个是能够看起来不像一个 30 年前的程序 我使用的是 Windows 7 我仅使用 Python 3 3
  • Ubuntu systemd 自定义服务因 python 脚本而失败

    希望获得有关 Ubuntu 中的 systemd 守护进程服务的一些帮助 我写了一个 python 脚本来禁用 Dell XPS 上的触摸屏 这更像是一个问题 而不是一个有用的功能 该脚本可以工作 但我不想一直启动它 这就是为什么我想到编写
  • Airflow 1.9 - 无法将日志写入 s3

    我在 aws 的 kubernetes 中运行气流 1 9 我希望将日志发送到 s3 因为气流容器本身的寿命并不长 我已经阅读了描述该过程的各种线程和文档 但我仍然无法让它工作 首先是一个测试 向我证明 s3 配置和权限是有效的 这是在我们
  • 使用另一个数据帧在数据帧中创建子列

    我对 python 和 pandas 很陌生 在这里 我有一个以下数据框 did features offset word JAPE feature manual feature 0 200 0 aa 200 200 0 200 11 bf
  • 无法通过 Python 子进程进行 SSH

    我需要通过堡垒 ssh 进入机器 因此 该命令相当长 ssh i
  • rpy2 无法加载外部库

    希望有人能帮忙解决这个问题 R版本 2 14 1rpy2版本 2 2 5蟒蛇版本 2 7 3 一直在尝试在 python 脚本中使用 rpy2 加载 R venneuler 包 该包以 rJava 作为依赖项 venneuler 和 rJa
  • 用于插入或替换 URL 参数的 Django 模板标签

    有人知道 Django 模板标签可以获取当前路径和查询字符串并插入或替换查询字符串值吗 例如向 some custom path q how now brown cow page 3 filter person 发出请求 电话 urlpar

随机推荐

  • 【计算机毕业设计】232流浪动物领养信息系统

    一 系统截图 需要演示视频可以私聊 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术 让传统数据信息的管理升级为软件存储 归纳 集中处理数据信息的管理方式 本流浪动物领养信息系统就是在这样的大环境下诞生 其可以帮助管理者在短时间内处理
  • Windows、Linux中std::this_thread::get_id()导致的Qt中sql执行报Driver not loaded错误

    Windows Linux中std this thread get id 导致的Qt中sql执行报Driver not loaded错误 抽象代码 void dosomework std ostringstream oss oss lt l
  • QTcpSocket 发送数据的几种方法

    1 QTcpSocket 继承于QAbstractSocket继承于QIODevice 2 QTcpSocket 提供的几种接收和发送数据方法 write const char qint64 qint64 write const char
  • 一百、Kettle(9.3.0)连接ClickHouse

    注意 低版本的kettle即使装ClickHouse驱动包后也不一定支持ClickHouse数据库连接 具体kettle从什么版本开始支持ClickHouse没测试过 只有高版本的kettle在安装ClickHouse驱动包后才支持Clic
  • 关于Winsows安装baselines的问题

    关于Winsows安装baselines的问题 windows是否可以使用baselines 根据GitHub上关于baselines的介绍 只有Linux和MAC OS给了配置说明 用pip在windows上安装的baselines只有最
  • HTML获取当前选中的li标签

    获取该class下的li标签 layui tab title li click function li标签下标默认为0 var liindex this index
  • foreach跳出本次/当前循环与终止循环方法及switch跳出方法

    目录 1 普通for循环 2 java中的foreach循环 3 js中的foreach循环 4 switch 1 普通for循环 continue 当满足某个条件时 想要跳出本次循环继续执行下次循环 break 满足某个条件的时候 终止f
  • 遗传算法优化BP神经网络的原理是什么

    遗传算法优化BP神经网络的原理是通过进行大量重复的试验 使用遗传算法来改进和优化神经网络的参数 以使神经网络能够更好地完成特定任务 遗传算法通过进化算法对神经网络中的参数进行重新调整 从而获得更好的性能
  • SQL中的CASE WHEN使用 .

    Case具有两种格式 简单Case函数和Case搜索函数 简单Case函数 CASE sex WHEN 1 THEN 男 WHEN 2 THEN 女 ELSE 其他 END Case搜索函数 CASE WHEN sex 1 THEN 男 W
  • 萤石摄像头RTSP流获取(黑屏解决)

    前言 在获取萤石摄像头RTSP视频流时 视频流获取不成功 黑屏并且一直显示缓冲中 下面对获取过程中查阅的资料和解决方案做一下汇总 打开RTSP 在萤石云视频APP中打开RTSP 我的 工具 局域网设备预览 开始扫描 选择摄像头 设置 更多设
  • 本地代码上传github

    怎么将新创建的本地代码上传到github上 这里简单的记录一下 我喜欢使用命令行 这里全用命令行来实现 不了解git命令的可以去了解下 1 先在github中创建仓库 2 回到你本地项目路径下右击打开git 没有的自行安装即可 3 初始化
  • ios.js?v=7c33aa19:1183 Uncaught (in promise) AxiosError {message: ‘Request failed with status code 4

    ios js v 7c33aa19 1183 Uncaught in promise AxiosError message Request failed with status code 404 name AxiosError code E
  • mysql中 or的使用方法,mysql条件查询中与or同时使用时的注意事项!!

    我们在日常的crud开发中 经常会遇到查询数据不是预期效果的问题 但是有感觉自己的查询语句没什么问题呀 怎么会出错呢 今天我也中招了 就很烦 sql如下 在查询语句中我们有一个条件是year 2021 但是查询结果还包含了2020的数据 这
  • Windows WSL配置ubuntu环境并登录

    一 什么是WSL wsl即适用于Windows的Linux子系统 Windows subsystem for Linux 二 Windows WSL配置ubuntu环境 1 管理员运行cmd 执行以下命令启用 适用于 Linux 的 Win
  • Codeforces Round 739 (Div. 3)

    A Dislike of Threes AC代码 include
  • Git的版本和分支管理

    1 http blog csdn net xiahouzuoxin article details 9393119 2 http blog csdn net xiahouzuoxin article details 9398629 3 ht
  • Qt在linux系统中执行shell命令

    在linux系统下 Qt执行shell命令的方式有3种 1 QProcess execute ls 2 system ls 3 QProcess process new QProcess process gt start ls 注1 以上3
  • 解决ubuntu20搜狗输入法输入不了中文问题

    解决在ubuntu上安装好搜狗输入法后无法输入中文 首先按照官网的安装步骤安装 Ubuntu搜狗输入法安装指南 注意不要忘记安装依赖 输以下命令进行安装 sudo apt install libqt5qml5 libqt5quick5 li
  • 接口测试的测试用例该怎么写呢?

    作者 字节开发测试 链接 https www zhihu com question 305629217 answer 2530044958 来源 知乎 著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处 一 什么是接口 接口
  • Python的exec

    目录 exec 简单使用 动态执行简单的字符串代码 动态执行较复杂的代码 执行文件中的Python代码 在exec中传参 使用中遇到的问题 参考 exec 简单使用 个人比较喜欢用Python里面的exec 可以用来动态执行字符串代码 在f