Python类和全局与局部变量

时间:2015-06-04 14:15:53

标签: python class namespaces 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)

输出结果为:

outside func
inside func
inside C

另一段代码是:

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)))

输出结果为:

[‘in the class’, 'in the class’]
['not in class’, 'not in class’]

问题是:

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

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

    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)
    

    输出结果为:

    inside func
    inside func
    inside func
    

    编辑2:

    事实上,这是this question的重复,因为正如Martijn Pieters所说:

      

    答案指出:如果在一个类体中分配了一个名称,   几乎在一开始。您已分配给my_str,使其成为相同的案例   就像那里一样。注释掉该行意味着您不再分配   到my_str,使其与x相同。

1 个答案:

答案 0 :(得分:5)

这里有四个范围:

  1. 全球范围
  2. 功能范围
  3. 班级主体
  4. lambda范围
  5. 创建类语句时,类主体作为函数将执行,并且该函数的本地名称空间将被执行。用作类属性。

    但是,一个类体一个范围,因此与函数的行为不同。在函数体中,绑定定义范围;分配给函数中的名称,并将其标记为本地名称。在课程中,分配名称会使其成为全局,直到您实际完成作业。

    因此,您的第一次 print()调用会发现my_str为全局,因为您绑定到该名称的类主体中的以后。这是班级机构没有参加范围的结果。

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

    的原因

    最后,您分配到类主体中的本地名称my_str,并打印该本地名称。

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

相关问题