{cd2>在下面的代码中工作。在
cc
赋值在一个类中使用相同的列表理解,在Python2中工作,但在Python3中失败。在
是什么解释了这种行为?在
ml1 = "a b c".split()
ml2 = "1 2 3".split()
mc = [ i1 + i2 for i1 in ml1 for i2 in ml2 ]
class Foo(object):
cl1 = ml1
cl2 = ml2
cc1 = [ i1 for i1 in cl1 ]
cc2 = [ i2 for i2 in cl2 ]
cc = [ i1 + i2 for i1 in cl1 for i2 in cl2 ]
print("mc = ", mc)
foo = Foo()
print("cc = ", foo.cc)
我明白了:
^{pr2}$为什么没有定义类变量cl2
?注意,cc2
赋值工作正常,cc1
也一样。在理解中交换cl1
和{
版本:
(default-3.5) snafu$ python2 --version
Python 2.7.11+
(default-3.5) snafu$ python3 --version
Python 3.5.1+
Python规则的作用域与它们自己的作用域相同。你知道一个类的方法是如何不自动在类范围内查找变量的吗?在
这同样适用于类作用域内嵌套的任何函数作用域,包括list comprehension的作用域。在列表理解中对
^{pr2}$cl2
的查找绕过了类作用域,直接转到全局变量。它实际上是这样工作的:注意,
cl1
查找工作正常,因为这发生在类范围内,在理解之外,尽管语法上嵌套在理解中。They made that decision当Python引入genexps时,因为它捕捉到了一些常见的genexp错误。这也是cc1
和cc2
列表理解工作的原因;它们对类级别变量的唯一使用是在它们的外部(仅)for
iterable中。在在类语句中使用理解和生成器表达式是一团糟。不应该,但确实如此。坚持使用常规循环,或者在类语句之外运行理解,这样语义就更明显了。在
相关问题 更多 >
编程相关推荐