不能使用类级别的变量 - python

我有以下代码,这行不通:

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解释器进行了尝试。

参考方案

如《任择议定书》下的讨论所见,这里有两件事。

首先,在Python中,没有默认的对象或类范围,例如C ++中的隐式this。因此,在函数内部,作用域就是该函数,并且您没有“自由”名称访问类上对象上定义的变量。这就是我们必须传递self的原因-我们需要显式包含我们的对象(和类)的环境。这意味着如果我们有

class A:
    n = 5

我们只能在类级别的定义中或通过显式保存环境来访问n

class A:
    n = 5
    a = range(n) # legal, evaluated in the class definition, where 'A' is defined and 'n' is part of the statement.
    def f():
        x = self.n # legal. As long you do not override self.n same as next
        x = A.n # legal, this is the class variable scope
        x = n # Error - we do not have 'n' for free. Even worse, if 'n' is a global variable, we are using that.

其次,在Python 3中,与Python 2不同的是,列表理解成为了一种范围。不再有泄漏变量,并且class语句的主体实际上不是作用域(而是名称空间的定义),因此也没有定义实现理解的匿名函数的作用域。所以

class A:
    n = 5
    x = [n/a for a in range(n)]

可能被视为

class A:
    n = 5
    def _anonymous_function(param):
        return [n/a for a in range(param)]
    x = _anonymous_function(n)

这样,可能更清楚为什么n在一个地方而不是在另一个地方是合法的。在range(n)中,类似于答案的第二个代码片段中的第一个示例,我们仍在类名称空间定义语句中,并“参见” n。另一方面,在理解主体中,我们处于有范围的(匿名)环境中,因为n是命名空间定义,所以看不到A,因为它不在外部(全局)范围内。与其他示例相反,这就是它在此处中断的原因。在Python 2中,这将起作用。

python JSON对象必须是str,bytes或bytearray,而不是'dict - python

在Python 3中,要加载以前保存的json,如下所示:json.dumps(dictionary)输出是这样的{"('Hello',)": 6, "('Hi',)": 5}当我使用json.loads({"('Hello',)": 6,…

Python uuid4,如何限制唯一字符的长度 - python

在Python中,我正在使用uuid4()方法创建唯一的字符集。但是我找不到将其限制为10或8个字符的方法。有什么办法吗?uuid4()ffc69c1b-9d87-4c19-8dac-c09ca857e3fc谢谢。 参考方案 尝试:x = uuid4() str(x)[:8] 输出:"ffc69c1b" Is there a way to…

Python:使用两个列表进行字典 - python

如何使用python使用两个列表作为字典list_one_keys = ['key1', 'key2', 'key3', 'key4'] 嵌套列表:list_two_values = [['a1var1', 'a1var2', '…

Python:无法识别Pip命令 - python

这是我拍摄的屏幕截图。当我尝试在命令提示符下使用pip时,出现以下错误消息:pip无法识别为内部或外部命令,可操作程序或批处理文件。我已经检查了这个线程:How do I install pip on Windows?我所能找到的就是我必须将"C:\PythonX\Scripts"添加到我的类路径中,其中X代表python版本。如您在我的…

在返回'Response'(Python)中传递多个参数 - python

我在Angular工作,正在使用Http请求和响应。是否可以在“响应”中发送多个参数。角度文件:this.http.get("api/agent/applicationaware").subscribe((data:any)... python文件:def get(request): ... return Response(seriali…