在类方法中执行行为

13 浏览
0 Comments

在类方法中执行行为

以下代码在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的行为?我已经尝试在Python3中为exec函数传递全局和局部的字典,但是到目前为止没有成功。

--- 编辑 ---

阅读了Martijns的答案后,我进一步分析了这个问题。在下面的示例中,我将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