为什么在函数中调用exec()时无法检索数据?

10 浏览
0 Comments

为什么在函数中调用exec()时无法检索数据?

以下代码在Python2和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输出:

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

Python3输出:

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

为什么Python2会将`execute`函数内的变量`b`绑定到`exec`函数字符串中的值,而Python3不这样做?如何在Python3中实现Python2的行为?我已经尝试将字典传递给`exec`函数的globals和locals参数,但目前没有任何效果。

--- 编辑 ---

在阅读Martijns的答案后,我进一步分析了Python3。在下面的示例中,我将`locals()`字典作为`d`传递给`exec`,但`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)                     # 这将打印出42
    print(d['b'])                # 这将打印出1000000.0
    print(id(d) == id(locals())) # 这将打印出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

比较`d`和`locals()`的id的结果表明它们是同一个对象。但在这种情况下,`b`应该与`d['b']`相同。我的示例中有什么问题?

0