查看以下代码:
class a:
s = 'python'
b = ['p', 'y']
c = [x for x in s]
输出:
>>> a.c
['p', 'y', 't', 'h', 'o', 'n']
但是当我尝试用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
有效,为什么会这样?
答案 0 :(得分:6)
关于类的工作方式,列表推导中的变量范围并不是很多。在Python 3(but not in Python 2!)中,列表推导不会影响它们的范围:
>>> [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
装饰器:
>>> 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
列为列表。