Python 2.7转3.6:列表推导式用locals()失效改用globals()问题
为什么Python 3.6列表推导式里调用
locals()拿不到局部变量? 这个问题的核心是Python 2和Python 3对列表推导式的作用域处理逻辑完全不一样,咱们一步步拆解:
在Python 2里,列表推导式根本没有自己独立的作用域,它直接“共享”外层的局部作用域空间。所以你在推导式里调用
locals(),拿到的就是外层定义A、B、C的那个局部变量字典,自然能通过变量名取到对应的值。但从Python 3开始,列表推导式被改成了拥有专属嵌套作用域的结构,就像一个匿名的小函数一样。这时候你在推导式内部调用
locals(),拿到的是这个嵌套作用域自己的变量字典——而你的A、B、C都定义在外面的作用域里,这个小作用域的字典里根本没有这些键,所以get()返回None就不奇怪了。
你可以自己做个小验证,在推导式里打印locals()看看:
(A,B,C) = (1,2,3) myvars = ['A','B','C'] result = [print(locals()) or locals().get(var) for var in myvars]
在Python 3里运行这段代码,会发现每次打印的locals()里只有var这个当前循环的变量,完全看不到A、B、C的影子。
至于为什么globals()能生效,是因为globals()不管在哪个作用域调用,拿到的都是全局作用域的变量字典——如果你的A、B、C是定义在脚本顶层(全局作用域)的,那自然能通过globals()取到它们。
如果想在Python 3里用类似Python 2的逻辑,可以先把外层的局部变量字典存下来再用:
(A,B,C) = (1,2,3) myvars = ['A','B','C'] # 先把外层的locals存到变量里 outer_locals = locals() result = [outer_locals.get(var) for var in myvars] # 这样就能得到[1,2,3]了
内容的提问来源于stack exchange,提问作者Daniel C
相关产品推荐
相关产品推荐

