likes
comments
collection
share

python3中 exec 的局部变量获取失败问题解决过程记录

作者站长头像
站长
· 阅读数 3

这几日,有粉丝问我一个报错问题,说他在某个calss内,进行exec的时候,频繁报错。经定位得知,exec的拼装字符串中,有个变量。但奇怪的是,这个变量并没有成功拼接进去。 我当即告诉他,这是因为exec函数中全局变量和局部变量的原因,直接获取局部变量是不行的,粉丝说他也在网上找了很久解决办法,也感觉是这个原因,但是一直没有解决,网上的写法都试了,都不行。 于是,我意识到这块的知识点,可能并没有很好的普及,于是写了本文来普及一下,请大家跟随我的文章,一点点探究弄懂这一块儿...

首先,我们先看这样一段代码:

python3中 exec 的局部变量获取失败问题解决过程记录

运行之后,大家猜猜会输出什么?报错还是1? 答案:1

python3中 exec 的局部变量获取失败问题解决过程记录

看到了吧?这就是exec的作用,可以执行某一段字符串。而且这个字符串中不但新建了变量b,还引用了变量a。


那我们现在来升级一下难度:

python3中 exec 的局部变量获取失败问题解决过程记录

大家来猜测下输出是什么?报错还是5?

答案:报错...  

python3中 exec 的局部变量获取失败问题解决过程记录

看到了吧,这里就开始出现了局部变量的问题。


那我们现在假如给 这个b 在x函数中先声明一下,还会报错么?

python3中 exec 的局部变量获取失败问题解决过程记录

输出答案:3

python3中 exec 的局部变量获取失败问题解决过程记录

从这个结果我们可以看出,虽然没有报错,但exec的内容似乎并没有生效,b仍然是3。那我们是不是可以猜测,exec中声明的变量b,并非在这个x函数内成为局部变量,而是停留在最外层成为全局变量了呢?


于是,我们把这个print(b) 移动到了x函数外,看看输出:

python3中 exec 的局部变量获取失败问题解决过程记录

答案:

python3中 exec 的局部变量获取失败问题解决过程记录

是不是感到很意外?居然外侧的全局变量也没有?那这个exec中的b,似乎消失了?

原因是什么呢?请看以下解释:

exec() 是一个内置函数,可以动态用python来执行字符串,并返回表达式结果。

我们平时用法就是:exec(b=5) 这样简单的用法。

但,其实exec真正的官方写法是:

exec(object[, globals[, locals]])

其中 globalslocals参数是可选的,用于指定全局变量和局部变量的命名空间。

也就是说,其实exec是可以指定变量的作用域的...


还是上面这个b的问题,我们现在给它改造一下(加个globals()),让其可以生成全局变量b:

python3中 exec 的局部变量获取失败问题解决过程记录

打印结果:

python3中 exec 的局部变量获取失败问题解决过程记录

可以看到已经变成了全局变量。

然后,我们引申一下,我们知道,当函数内向打印某个变量,但这个变量并非局部变量,而是全局变量的时候。函数内打印的就是全局变量的值:

python3中 exec 的局部变量获取失败问题解决过程记录

结果:5

python3中 exec 的局部变量获取失败问题解决过程记录

但是如果说,这个函数内已经有了一个局部变量b,那么输出的结果就是:

python3中 exec 的局部变量获取失败问题解决过程记录

结果:3

python3中 exec 的局部变量获取失败问题解决过程记录

此时,如果你在外面也打印b:

python3中 exec 的局部变量获取失败问题解决过程记录

那么结果就是:3 5

python3中 exec 的局部变量获取失败问题解决过程记录

到此,我们知道了如何利用exec生成全局变量。而使用全局变量可以随便用。


那问题来了,如何在exec中,使用全局变量或局部变量呢?

使用全局变量:

python3中 exec 的局部变量获取失败问题解决过程记录

我们生成的变量b, 在exec中使用了全局变量a。

打印结果:1

python3中 exec 的局部变量获取失败问题解决过程记录


那如果exec中使用的是局部变量a呢?这个问题就是粉丝一开始犯难的问题了,如果直接这么写:

python3中 exec 的局部变量获取失败问题解决过程记录

那结果肯定是报错:

python3中 exec 的局部变量获取失败问题解决过程记录

其实想要成功的办法很简单,而且有俩种写法:

写法一:让b成为全局变量后得到a的值。

python3中 exec 的局部变量获取失败问题解决过程记录

结果:1

python3中 exec 的局部变量获取失败问题解决过程记录

写法二:利用中间值tmp,来接收a的值,再从locals空间提取出来再赋值给b

python3中 exec 的局部变量获取失败问题解决过程记录

结果:1

python3中 exec 的局部变量获取失败问题解决过程记录


好,到此,关于exec在某个class或def中,到底应该怎么用。上述已经全部写明。