我正在将项目从python 2.7更新到python 3.6.
我有一个列表理解,查找在python 2.7中工作的本地变量.当我切换到使用全局变量时,它只适用于python 3.6.
下面是一个说明问题的玩具示例.
相关代码是:
(A,B,C) = (1,2,3)
myvars = ['A','B','C']
Run Code Online (Sandbox Code Playgroud)
如果我执行以下代码:
[locals().get(var) for var in myvars]
Run Code Online (Sandbox Code Playgroud)
python 3.6中的返回值是:
[None, None, None]
Run Code Online (Sandbox Code Playgroud)
但是,python 2.7中的返回值是:
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
如果我使用globals执行以下代码:
[globals().get(var) for var in myvars]
Run Code Online (Sandbox Code Playgroud)
然后我在python 2.7和3.6中得到相同的结果:
[1, 2, 3]
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释为什么使用locals()的代码不再适用于python 3.6?
如果我们解释一个更基本的列表理解.我们可以看到为什么会这样:
>>> import dis
>>> dis.dis("[i for i in range(10)]")
1 0 LOAD_CONST 0 (<code object <listcomp>)
3 LOAD_CONST 1 ('<listcomp>')
6 MAKE_FUNCTION 0
9 LOAD_NAME 0 (range)
12 LOAD_CONST 2 (10)
15 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
18 GET_ITER
19 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
22 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
所以,在线9,我们看到list-comp实际上是一个被调用的函数(在使用生成器时你可能更习惯这个).因此,函数将拥有自己的一组局部变量,因为它位于一个单独的范围内 - 从而产生这种意外行为.
此外,正如所指出的@juanpa,"Python3中的新功能"文档明确说明了以下内容:
列表推导具有不同的语义:它们更接近于
list()构造函数内的生成器表达式的语法糖,特别是循环控制变量不再泄漏到周围的范围中.
另请注意,此页面上有一个错误页面:https://bugs.python.org/issue21161,但juanpa已经说服我这不是一个错误,因为它有明确记录以这种方式工作!
列表解析定义在Python 3新的范围,他们并没有在Python 2.做简单的说,A,B,和C是不是在Python 2列表理解局部变量.
顺便说一下,你可能应该一直使用显式的dict {'A': 1, 'B': 2, 'C': 3}而不是单独的变量.现在是解决这个问题的好时机.
| 归档时间: |
|
| 查看次数: |
260 次 |
| 最近记录: |