列表推导式中使用的变量在封闭作用域中¶
ID: py/leaking-list-comprehension
Kind: problem
Security severity:
Severity: warning
Precision: very-high
Tags:
- portability
- correctness
Query suites:
- python-security-and-quality.qls
在 Python 2 中,列表推导式在封闭作用域中进行求值,这意味着列表推导式的迭代变量在列表推导式之外是可见的。在 Python 3 中,迭代变量不再在封闭作用域中可见。
在列表推导式完成后,使用列表推导式迭代变量值的代码在 Python 2 和 Python 3 中的行为将不同。
建议¶
在外部作用域中显式地将变量设置为它在 Python 2 下运行时所持有的值。然后重命名列表推导式变量,以提高清晰度。
示例¶
在此示例中,x
最初被赋予值为 3。在 Python 3 中,x
将保持不变,因为列表推导式在其自身的作用域中进行求值。在 Python 2 中,列表推导式的求值发生在 two_or_three
的作用域中,将 x
设置为 2。
def two_or_three():
x = 3
[0 for x in range(3)]
return x # Will return 2 in Python 2 and 3 in Python 3.
print(two_or_three())
以下示例与上面的代码相同,但列表推导式变量已重命名,以确保它不会覆盖 x
。
def just_three():
x = 3
[0 for y in range(3)]
return x # Will return always return 3.
print(just_three())
参考资料¶
Python 教程:列表推导式.
Python 历史:从列表推导式到生成器表达式.
Python 语言参考:列表显示.