我有以下代码,但不起作用:
class Node:
n = 5
options = [ i / (n-1) for i in range(n)]
print("Success")
我得到的错误是:
Traceback (most recent call last):
File "/Users/ikkamens/Library/Preferences/PyCharm2019.2/scratches/counters.py", line 1, in <module>
class Node:
File "/Users/ikkamens/Library/Preferences/PyCharm2019.2/scratches/counters.py", line 3, in Node
options = [ i / (n-1) for i in range(n)]
File "/Users/ikkamens/Library/Preferences/PyCharm2019.2/scratches/counters.py", line 3, in <listcomp>
options = [ i / (n-1) for i in range(n)]
NameError: name 'n' is not defined
但是,以下更改的版本仍然有效:
class Node:
n = 5
options = [ i / 4 for i in range(n)]
print("Success")
为什么我可以在range
表达式中使用类级别变量,而不能在(n-1)
表达式中使用?这是一个解释器错误还是有一些规则来解释这种行为?我试过使用3.8和3.6口译员
我不知道为什么它不能以这种方式工作,但可能是口译员认为
(n-1)
在列表中是属于列表中的局部变量或循环的一部分。尽管我不确定你可以这样做
从OP下的讨论可以看出,这里有两件事
< P><强>第一< /强>,在Python中,没有默认对象或类作用域,如C++中的隐式^ {< CD1>}。因此,在函数内部,您的作用域就是该函数,并且您没有对类上对象上定义的变量的“自由”名称访问权。这就是我们必须传递self
的原因——我们需要显式包含对象(和类)的环境。这意味着如果我们有我们只能在类级别定义中访问
n
,或者通过显式保存环境:第二个,在Python3中,与Python2不同的是,列表理解被限定了范围。不再泄漏变量,并且
class
语句的主体实际上不是一个作用域(而是一个名称空间的定义),因此也不是定义实现理解的匿名函数的作用域。所以可能被视为
通过这种方式,也许可以更清楚地解释为什么
n
在一个地方合法,而在另一个地方不合法。在range(n)
中,与答案中第二个代码段中的第一个示例类似,我们仍然在类名称空间定义语句中,并“参见”n
。另一方面,在理解体中,我们处于一个作用域(匿名)环境中,没有看到n
,因为它不在外部(全局)作用域中,因为A
是一个命名空间定义。这就是它在这里中断的原因,与另一个示例相反。在Python2中,这是可行的相关问题 更多 >
编程相关推荐