Python 2 和 Python 3 中 exec 函数的行为

2024-01-11

以下代码给出了不同的输出Python2 and in Python3:

from sys import version

print(version)

def execute(a, st):
    b = 42
    exec("b = {}\nprint('b:', b)".format(st))
    print(b)
a = 1.
execute(a, "1.E6*a")

Python2 prints:

2.7.2 (default, Jun 12 2011, 15:08:59) [MSC v.1500 32 bit (Intel)]
('b:', 1000000.0)
1000000.0

Python3 prints:

3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)]
b: 1000000.0
42

为什么Python2绑定变量b在 - 的里面execute函数的字符串中的值exec函数,同时Python3不这样做吗?我怎样才能实现以下行为Python2 in Python3?我已经尝试将全局变量和本地变量的字典传递给exec函数于Python3,但到目前为止没有任何效果。

- - 编辑 - -

阅读 Martijns 的回答后,我进一步分析了这一点Python3。在下面的例子中我给出locals()字典作为d to exec, but d['b']打印除打印以外的其他内容b.

from sys import version

print(version)

def execute(a, st):
    b = 42
    d = locals()
    exec("b = {}\nprint('b:', b)".format(st), globals(), d)
    print(b)                     # This prints 42
    print(d['b'])                # This prints 1000000.0
    print(id(d) == id(locals())) # This prints True
a = 1.
execute(a, "1.E6*a")

3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)]
b: 1000000.0
42
1000000.0
True

id 的比较d and locals()表明它们是同一个对象。但在这些条件下b应该是一样的d['b']。我的例子有什么问题吗?


之间有很大的区别exec在Python 2和exec()在Python 3中。你正在治疗exec作为一个函数,但它确实是一个陈述在Python 2中。

由于这种差异,您无法在 Python 3 中使用以下命令更改函数作用域中的局部变量exec,尽管在 Python 2 中是可能的。甚至之前声明的变量也没有。

locals()只反映一个方向的局部变量。以下内容在 2 或 3 中都不起作用:

def foo():
    a = 'spam'
    locals()['a'] = 'ham'
    print(a)              # prints 'spam'

在 Python 2 中,使用exec语句意味着编译器知道关闭本地范围优化(从LOAD_FAST to LOAD_NAME例如,在局部和全局范围内查找变量)。和exec()作为一个函数,该选项不再可用,并且函数作用域现在是always优化。

此外,在 Python 2 中,exec语句显式复制在中找到的所有变量locals()回到函数 locals 使用PyFrame_LocalsToFast,但前提是没有globals and locals提供了参数。

正确的解决方法是为您的应用程序使用新的命名空间(字典)exec() call:

def execute(a, st):
    namespace = {}
    exec("b = {}\nprint('b:', b)".format(st), namespace)
    print(namespace['b'])

The exec()文档 https://docs.python.org/3/library/functions.html#exec对于这个限制非常明确:

Note:默认locals按照功能描述进行操作locals()如下:对默认值的修改locals不应尝试字典。通过明确的locals如果您需要在函数执行后查看代码对局部变量的影响,请查看字典exec()返回。

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

Python 2 和 Python 3 中 exec 函数的行为 的相关文章

随机推荐

  • 为 exec ANT 任务启用控制台输出

    在 Eclipse 中 我使用以下 Macrodef 启动一个 html 页面 其中嵌入了 ANT 中的 swf
  • 对两个黑白图像进行异或并求和

    从两张图像开始im1 and im2使用PIL模块创建 我们有相应的黑白图像 bw im1 im1 convert 1 and bw im2 im2 convert 1 每个像素的bw im2 and bw im2是 0 或 256 假设两
  • Google Analytics 实时如何工作?

    我想知道 Google Analytics 实时用户界面是如何工作的 技术是什么 他们是否使用客户端的长轮询 通过将实时信息从服务器传送到客户端来保持 UI 统计数据即时更新 我刚刚在网络选项卡上打开 Chrome 开发工具 并且有一个无限
  • IIS 7.0 上的 ETag

    IIS 中的 Etag 是否默认启用 如果没有 请告诉我如何打开它们 Etag 开启 默认设置为 0 http attosol com etag and iis demystified http attosol com etag and i
  • Python 更新 Github 远程存储库上的文件,无需本地工作目录

    这是关于在没有本地工作目录的情况下推送到远程存储库的问题的后续问题 Python 将文件推送到 Github 远程仓库 无需本地工作目录 https stackoverflow com questions 39737192 python p
  • Python - 将 CSV 转换为对象 - 代码设计

    我有一个小脚本 用于读取包含员工的 CSV 文件 并对这些数据执行一些基本操作 我们读入数据 import gd dump 并创建一个Employees对象 包含一个列表Employee对象 也许我应该想一个更好的命名约定 哈哈 然后我们调
  • 作为图形 IDE 用户,我应该对传统编辑器感兴趣吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何确定节点中用户的IP地址

    如何确定控制器内给定请求的 IP 地址 例如 快递 app post get ip address function req res need access to IP address here In your request https
  • 使用来自 C99 的库在 Windows 上使用 TCC 编译文件

    所以最新版本的TCC据说实现了C99的一些功能 但是 我发现它不包括C99的数学库 有没有办法让它在 Windows 上使用更多 C99 的库 我用 google 搜索了一下 发现了一些主要与 Linux 相关的建议 但对于这个项目 我需要
  • org.apache.http.conn.HttpHostConnectException:与 https://jazz.net 的连接被拒绝

    我已将我的工作灯从 5 0 5 升级到 5 0 6 当我在 5 0 5 上工作时 它工作正常 但当我在更新版本的工作灯 5 0 6 中使用相同的代码时 它给了我这个错误 响应 apps services api RTMLight commo
  • 从 XCode 中的 .strings 文件读取字符串

    我是 iOS 新手 我有一个 strings 文件 其中存储了一个免责声明 当我的应用程序打开时可以查看该免责声明 但是 我无法弄清楚如何从 disclaimer strings 文件中调用 免责声明 字符串 如有帮助 将不胜感激 另外 感
  • 如何通过哈希比较限制 API 密钥的使用

    我目前正在使用Spotify in my Android应用程序 但我需要使用Secret为了刷新令牌等等 我想传达我的秘密Backend到应用程序 因此秘密并不驻留在APK并且反编译时找不到 我读过很多关于保护应用程序中的秘密的内容 通过
  • RobotFramework:超出启动关键字的最大限制

    我是 RobotFramework 的新手 我正在尝试做一个简单的测试 使用 Log 关键字打印 Hello world 并从 java 类获取值 我在 Ride 上使用 jybot Settings Library robot MyTes
  • 是的,嵌套模式验证

    我正在尝试根据用户选择的选择选项有条件地验证对象 问题是我正在渲染货币列表 并且在尝试将其设为必填字段时遇到巨大困难 因为我必须传入一个空的对象开始 我的代码堆栈是 React Formik 和 Yup 所有最新版本 对象模式 catego
  • 防止同时触摸多个按钮

    在iOS中 是否有办法防止包含多个按钮 兄弟 的UIView同时被触摸 例如 可以通过两次触摸同时点击两个并排的不重叠按钮 设置 UIView exclusiveTouch
  • 如何为 Maven/Surefire 和 Eclipse 加载不同的 logback 配置

    我想在 Eclipse 和 Maven surefire 插件 中为我的单元测试使用不同的默认 logback 配置 基本上 我希望将测试期间生成的任何日志发送到 Eclipse 中的控制台或 Maven 的文件 目前 我有一个包含两个附加
  • Java Applet 中的背景图像

    如何在 Java Applet 中设置背景图像 假设我希望 background gif 成为我的 java applet 类中的背景 但我该怎么做呢 我认为没有一个函数可以做到这一点 但是您可以扩展一个Panel 它可以充当一个简单的组件
  • backbone.js 的跨浏览器如何?

    我们正在使用多种浏览器类型 网络 移动设备 平板电脑和智能电视 我们正在为我们的 mvc 寻找backbone js backbone js 是否有任何已知的跨浏览器限制 我认为这与 Backbone 关系不大 而与您使用的 HTML 和
  • 什么是陈旧状态?

    我在维基百科上阅读有关对象池模式的内容 http en wikipedia org wiki Object pool http en wikipedia org wiki Object pool 并且它提到 危险的陈旧状态 陈旧 状态到底是
  • Python 2 和 Python 3 中 exec 函数的行为

    以下代码给出了不同的输出Python2 and in Python3 from sys import version print version def execute a st b 42 exec b nprint b b format