具有列表理解的类变量的范围 [英] Scope of class variable with list comprehension

查看:53
本文介绍了具有列表理解的类变量的范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看看下面的代码:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆