我在理解以下代码的结果时遇到了什么问题:
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:
我认为这与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相同。
答案 0 :(得分:5)
这里有四个范围:
创建类语句时,类主体作为函数将执行,并且该函数的本地名称空间将被执行。用作类属性。
但是,一个类体不一个范围,因此与函数的行为不同。在函数体中,绑定定义范围;分配给函数中的名称,并将其标记为本地名称。在课程中,分配名称会使其成为全局,直到您实际完成作业。
因此,您的第一次 print()
调用会发现my_str
为全局,因为您绑定到该名称的类主体中的以后。这是班级机构没有参加范围的结果。
接下来,定义一个lambda并调用它。永远不会在该lambda中分配my_str
,因此必须在父范围中找到它。这里的类体不是范围,下一个范围是函数范围。这就是该行打印inside func
。
最后,您分配到类主体中的本地名称my_str
,并打印该本地名称。
当您删除作业时,班级中的名称将被视为非本地名称;第一个和最后一个print()
语句现在是相等的,只需根据正常的范围规则查找名称。