PythonNote041---exec变量作用域问题

本文探讨了在Python中使用exec函数执行字符串代码时遇到的变量作用域问题。当exec位于函数内部时,其定义的变量无法在函数外部引用。文章通过示例解释了这一现象,并提供了两种解决方案:一是使用globals()参数将变量注册到全局空间,二是创建一个自定义字典来保存exec的执行结果。这两种方法分别有其优缺点,如全局污染和避免污染。最后,文章给出了相关参考资料链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Intro

  分析时,常常拼接字符串,作为代码执行。此时会调用exec方法,在命令行或者jupyter中执行,exec执行的变量,在外部可以引用。而嵌套在函数内部时,则不能引用。看几个例子:

exec_str ="""
a = 1
"""
exec(exec_str)
print(f'a={a}')
a=1
def exe_f():
    exec_str = f"""
fun_y = 1
print(f"exec_str:fun_y=",fun_y)
"""
    exec(exec_str)
    print(f"exe_f:fun_y=",fun_y)

exe_f()
exec_str:fun_y= 1



---------------------------------------------------------------------------

NameError                                 Traceback (most recent call last)

~\AppData\Local\Temp\ipykernel_24724\1254702322.py in <module>
      7     print(f"exe_f:fun_y=",fun_y)
      8 
----> 9 exe_f()


~\AppData\Local\Temp\ipykernel_24724\1254702322.py in exe_f()
      5 """
      6     exec(exec_str)
----> 7     print(f"exe_f:fun_y=",fun_y)
      8 
      9 exe_f()


NameError: name 'fun_y' is not defined

原理见ref[1],简言之,exec时,变量fun_y并没有注册到局部空间,因此引用时获取失败。

解法

有几种方法,依次看下

把exec执行结果保存到globals()

def exe_f():
    exec_str = f"""
fun_y = 1
print(f"exec_str:fun_y=",fun_y)
"""
    exec(exec_str,globals())
    print(f"exe_f:fun_y=",fun_y)

exe_f()
print(f"globals:fun_y=",fun_y)
exec_str:fun_y= 1
exe_f:fun_y= 1
globals:fun_y= 1

该方法可能会导致全局变量被污染

自定义字典

def exe_f():
    self_dict = {}
    exec_str = f"""
fun_y1 = 1
print(f"exec_str:fun_y1=",fun_y1)
"""
    exec(exec_str,globals(),self_dict)
    print(f"exe_f:fun_y=",self_dict['fun_y1'])

exe_f()
var_name = 'fun_y1'
print(f'locals() {var_name}:{locals().get(var_name, None)}')
exec_str:fun_y1= 1
exe_f:fun_y= 1
locals() fun_y1:None

此时不会污染全局变量

Ref

[1] https://blog.youkuaiyun.com/LutingWang/article/details/124133994

                                2022-11-27 于南京市江宁区

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值