具有列表理解的类变量的范围 [英] Scope of class variable with list comprehension
问题描述
看看下面的代码:
class a:
s = 'python'
b = ['p', 'y']
c = [x for x in s]
输出:
>>> a.c
['p', 'y', 't', 'h', 'o', 'n']
但是当我尝试使用if限制列表时
but when i try to limit the list with if:
class a:
s = 'python'
b = ['p', 'y']
c = [x for x in s if x in b]
显示以下异常:
Traceback (most recent call last):
File "<pyshell#22>", line 1, in <module>
class a:
File "<pyshell#22>", line 4, in a
c = [x for x in s if x in b]
File "<pyshell#22>", line 4, in <listcomp>
c = [x for x in s if x in b]
NameError: global name 'b' is not defined
如果make global b
有效,为什么会这样?
If a make global b
it works, why this is happening?
推荐答案
与列表工作方式有关,这与列表理解中的变量作用域无关.在Python 3中(但在Python 2中没有!),列表理解不会影响它们的作用域:
This isn't so much about the variable scope in list comprehensions as about the way classes work. In Python 3 (but not in Python 2!), list comprehensions don't affect the scope around them:
>>> [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> i
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined
>>> i = 0
>>> [i for i in range(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> i
0
但是,当您在类中执行此操作时,它不会像在模块或函数的本地范围内那样在类属性中寻找b
.要执行您想做的事情,请使用@property
装饰器:
However, when you do that in a class, it won't look for b
among the class attributes the way it would in the local scope of a module or function. To do what you are trying to do, use the @property
decorator:
>>> class a:
... s = 'python'
... b = 'py'
... @property
... def c(self):
... return [x for x in self.s if x in self.b]
...
>>> A = a()
>>> A.c
['p', 'y']
此外,请记住字符串也是可迭代的(它们只是其组成字符的列表),因此无需显式地将b
列为列表.
Also, remember that strings are iterable too (they're just lists of their component characters), so no need to explicitly make b
a list.
这篇关于具有列表理解的类变量的范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!