小编给大家分享一下Python在局部变量域中执行代码的方法是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!
<强>问题强>
你想在使用范围内执行某个代码片段,并且希望在执行后所有的结果都不可见。
<强>解决方案强>
为了理解这个问题,先试试一个简单场景。首先,在全局命名空间内执行一个代码片段:
在祝辞祝辞=13 在在在exec (& # 39; b=a + 1 & # 39;) 在在在打印(b) 14 祝辞祝辞祝辞
然后,再在一个函数中执行同样的代码:
在祝辞祝辞def测试(): …=13 …exec (& # 39; b=a + 1 & # 39;) …打印(b) … 在在在测试() 回溯(最近的电话): 文件“& lt; stdin>“, 1号线,在& lt; module> 文件“& lt; stdin>“, 4号线,在测试 NameError:全局名称& # 39;b # 39;没有定义 祝辞祝辞祝辞
可以看出,最后抛出了一个NameError异常,就跟在<代码> exec() 代码>语句从没执行过一样。要是你想在后面的计算中使用到<代码> exec() 代码>执行结果的话就会有问题了。
为了修正这样的错误,你需要在调用<代码> exec() 代码>之前使用<代码>当地人()代码>函数来得到一个局部变量字典。之后你就能从局部字典中获取修改过后的变量值了。例如:
在祝辞祝辞def测试(): …=13 …当地人loc=() …exec (& # 39; b=a + 1 & # 39;) …b=loc [& # 39; b # 39;】 …打印(b) … 在在在测试() 14 祝辞祝辞祝辞
<>强讨论强>
实际上对于<代码> exec() 代码>的正确使用是比较难的。大多数情况下当你要考虑使用<代码> exec() 代码>的时候,还有另外更好的解决方案(比如装饰器,闭包,元类等等)。
然而,如果你仍然要使用exec(),本节列出了一些如何正确使用它的方法。默认情况下,exec()会在调用者局部和全局范围内执行代码。然而,在函数里面,传递给exec()的局部范围是拷贝实际局部变量组成的一个字典。因此,如果exec()如果执行了修改操作,这种修改后的结果对实际局部变量值是没有影响的。下面是另外一个演示它的例子:
在祝辞祝辞def test1 (): …x=0 …exec (& # 39; x +=1 & # 39;) …打印(x) … 在在在test1 () 0 祝辞祝辞祝辞
上面代码里,当你调用<代码>当地人()代码>获取局部变量时,你获得的是传递给<代码> exec() 代码>的局部变量的一个拷贝。通过在代码执行后审查这个字典的值,那就能获取修改后的值了。下面是一个演示例子:
在祝辞祝辞def test2 (): …x=0 …当地人loc=() …打印(& # 39;:& # 39;,loc) …exec (& # 39; x +=1 & # 39;) …打印(& # 39;后:& # 39;,loc) …打印(& # 39;x=& # 39;, x) … 在在在test2 () :{& # 39;x # 39;: 0} 后:{& # 39;loc # 39;: {…},& # 39;x # 39;: 1} x=0 祝辞祝辞祝辞
仔细观察最后一步的输出,除非你将loc中被修改后的值手动赋值给x,否则x变量值是不会变的。
在使用<代码>当地人()代码>的时候,你需要注意操作顺序。每次它被调用的时候,<代码>当地人()代码>会获取局部变量值中的值并覆盖字典中相应的变量。请注意观察下下面这个试验的输出结果:
在祝辞祝辞def test3 (): …x=0 …当地人loc=() …打印(loc) …exec (& # 39; x +=1 & # 39;) …打印(loc) …当地人() …打印(loc) … 在在在test3 () {& # 39;x # 39;: 0} {& # 39;loc # 39;: {…},& # 39;x # 39;: 1} {& # 39;loc # 39;: {…},& # 39;x # 39;: 0} 祝辞祝辞祝辞
在祝辞祝辞def test3 (): …x=0 …当地人loc=() …打印(loc) …exec (& # 39; x +=1 & # 39;) …打印(loc) …当地人() …打印(loc) … 在在在test3 () {& # 39;x # 39;: 0} {& # 39;loc # 39;: {…},& # 39;x # 39;: 1} {& # 39;loc # 39;: {…},& # 39;x # 39;: 0} 祝辞祝辞祝辞
注意最后一次调用<代码>当地人()代码>的时候x的值是如何被覆盖掉的。
作为<代码>当地人()代码>的一个替代方案,你可以使用你自己的字典,并将它传递给<代码> exec()> 代码。例如:
在祝辞祝辞def test4 (): …=13 …loc={& # 39;一个# 39;:} …glb={} …exec (& # 39; b=a + 1 & # 39;, glb, loc) …b=loc [& # 39; b # 39;】 …打印(b) … 在在在test4 () 14 祝辞祝辞在Python在局部变量域中执行代码的方法是什么