Python类和全局与局部变量

Dar*_*gor 6 python namespaces class global-variables

我有一个问题,了解以下代码片段的结果发生了什么:

my_str = "outside func"
def func():
    my_str = "inside func"
    class C():
        print(my_str)
        print((lambda:my_str)())
        my_str = "inside C"
        print(my_str)
Run Code Online (Sandbox Code Playgroud)

输出是:

outside func
inside func
inside C
Run Code Online (Sandbox Code Playgroud)

另一段代码是:

my_str = "not in class"
class C:
    my_str = "in the class"
    print([my_str for i in (1,2)])
    print(list(my_str for i in (1,2)))
Run Code Online (Sandbox Code Playgroud)

输出是:

[‘in the class’, 'in the class’]
['not in class’, 'not in class’]
Run Code Online (Sandbox Code Playgroud)

问题是:

  1. 每个print()语句中发生了什么?
  2. 任何人都可以解释为什么 print()语句从不同的命名空间中获取字符串?

编辑1:

我认为这与这个问题不同,因为我谦卑地认为那里的答案并不能解释这种变化:

my_str = "outside func"
def func():
    my_str = "inside func"
    class C():
        print(my_str)
        print((lambda:my_str)())
       #my_str = "inside C"
        print(my_str)
Run Code Online (Sandbox Code Playgroud)

输出是:

inside func
inside func
inside func
Run Code Online (Sandbox Code Playgroud)

编辑2:

事实上,这是与这个问题的重复,因为Martijn Pieters说:

答案说明:如果一个名称被分配到一个类体内,几乎在开始时.您已分配给my_str,使其与y相同.注释掉该行意味着您不再分配给my_str,使其与x相同.


Mar*_*ers 5

这里有四个范围:

  1. 全球范围
  2. 功能范围
  3. 班级的身体
  4. lambda范围

在创建类语句时,类主体作为函数执行,并且该"函数"的本地名称空间用作类属性.

但是,类主体不是范围,因此与函数的行为不同.在函数体中,绑定定义范围; 分配给函数中的名称,并将其标记为本地名称.在类中,在实际执行赋值之前,分配名称会使其成为全局名称.

因此,您的第一个 print()调用将my_str作为全局调用,因为稍后在类主体中绑定到该名称.这是班级机构没有参加范围的结果.

接下来,定义一个lambda并调用它.my_str从未在该lambda中分配,因此必须在父范围中找到它.这里的类体不是范围,下一个范围是函数范围.这就是该行打印的原因inside func.

最后,分配给my_str类体中的本地名称,然后打印该本地名称.

删除作业的那一刻,班级中的名称被视为非本地名称; 第一个和最后一个print()语句现在是相等的,只需根据正常的范围规则查找名称.

  • @PabloGalindoSalgado:仅限您的编辑*确认*该帖子是一个骗子. (3认同)