在前面《Python 代码动态执行初探》中讲到过如何用exec和eval函数动态执行代码,也描述了如何限制其命名空间,避免动态代码造成环境“污染”。
不过,有的时候,我们的确想要让动态代码生成一些局部或全局的定义——比如一个变量名——让原始代码或者后面的动态代码可以继续使用。像下面这样直接定义是无法生效的:
def f():
a = 1
exec("a = 3")
print(a)
此时打印的结果会是1,也就是说exec中对a的修改被丢弃了。不过可以采用locals参数来取回修改:
def foo():
ldict = {}
exec("a=3",globals(),ldict)
a = ldict['a']
print(a)
这里的打印结果就是3了。
本文的示例代码取自stack overflow的一篇问答
2021-11-17更新
注意:在pycharm里,默认的source root就是项目根目录,这时不要在项目内部,再设置source folder了,要不然就会出现同一个Module,可以从不同级别import的问题。
我就曾经犯了这个错误,把一个项目子文件夹设置成source folder:
导致自动生成的import,全都少一级目录,比如像下面这样:
from core.data.Action import Action
class Executor
而实际上写全路径也能成功import:
from simplerpa.core.data.Action import Action
class STATE
这个错误还很隐蔽,因为平时使用没有任何问题,直到有一个类成员属性承担了本文上面提到的ldict功能,但里面保存的变量,在Executor执行的时候都丢失了,才发现原来从不同路径import的同一个类,不能共享类成员。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。