exec如何与当地人合作?
我以为这会打印3,但它打印1:
def f(): a = 1 exec("a = 3") print(a)
这个问题在Python3的bug列表中有所讨论。 最终,要获得这种行为,你需要做的:
def foo(): ldict = locals() exec("a=3",globals(),ldict) a = ldict['a'] print(a)
如果你在exec
上检查Python3文档 ,你会看到下面的注释:
默认的locals的作用与下面的函数
locals()
所描述的一样:不应该尝试修改默认的locals字典。 如果需要在函数exec()返回后看到代码对本地代码的影响,则传递一个显式的本地字典。
回过头来看这个bug报告的具体信息 ,Georg Brandl说:
要dynamic地修改函数的局部性是不可能的,没有几个后果: 通常,函数局部variables不是存储在字典中,而是一个数组 ,其索引是在编译时从已知的语言环境中确定的。 这至less与exec添加的新本地人相冲突。 旧的exec语句绕过了这个,因为编译器知道如果一个没有globals / locals args的exec在一个函数中出现,那这个名字空间将是“unoptimized”,即不使用locals数组。 由于exec()现在是一个正常的函数, 编译器不知道“exec”可能会绑定什么,因此不能特别处理 。
重点是我的。
所以它的要点是,Python3可以更好地优化局部variables的使用,默认情况下不允许这种行为。
为了完整起见,正如上面的注释中所提到的那样,Python 2.X中的预期工作方式如下:
Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> def f(): ... a = 1 ... exec "a=3" ... print a ... >>> f() 3
如果你在一个方法中,你可以这样做:
class Thing(): def __init__(self): exec('self.foo = 2') x = Thing() print(x.foo)
你可以在这里阅读更多