这段代码在幕后发生了什么? pythontutor对此没有帮助。
一些问题:为什么ok_then()“看到”变量sure.d?如果该模块中的每个函数都能看到它,那么命名变量sure.d的意义何在?
def ok_then():
print(ok_then.c)
print(sure.d)
def sure():
pass
def set_vals(c,d):
ok_then.c = c
sure.d = d
>>> set_vals(3, 4)
>>> ok_then
3
4
最后,为什么会出现这个错误?从范围的角度来看,ok_then.c和sure.d正在发生一些事情,但我不清楚究竟是什么。
def ok_then():
print(a)
print(b)
def sure():
pass
def set_vals(c,d):
a = c
b = d
>>> set_vals(3,4)
>>> ok_then()
Traceback (most recent call last):
File "<pyshell#9>", line 1, in <module>
ok_then()
File "C:/Users/test_set_vals.py", line 2, in ok_then
print(a)
NameError: name 'a' is not defined
答案 0 :(得分:3)
简而言之,因为包括函数定义在内的所有内容都是对象。其次,范围。
在第一个示例中,您定义了三个函数ok_then,sure和set_vals。在set_vals中,您可以为属性&#34; c&#34;分配一个值。函数ok_then,以及属性&#34; d&#34;功能肯定。这是一件奇怪的事情,但它在Python中是允许的。它的工作原理是因为你已经定义了ok_then并确定它们在当前模块范围内。
在你的第二个例子中,ok_then尝试引用变量&#34; a&#34;和&#34; b&#34;。它们不存在于该范围内。它们存在的唯一范围是在函数set_vals中。
请注意,调用set_vals.a不是访问函数范围内的变量的方法。您可能希望为该类型的行为创建一个类。
答案 1 :(得分:2)
两个示例的不同之处在于,第一个c
和d
是对象的属性,它们是函数ok_then
和{{ 1}}。非常喜欢这样:
sure
这将打印3,因为printC当然可以&#34;参见&#34; cdholder因此能够访问它的属性。
在第二个示例中,class CDHolder:
pass # empty class
cdholder = CDHolder() # cdholder is now an object
cdholder.c = 3 # the attribute "c" is now 3
function printC():
print( cdholder.c )
printC()
和a
是局部变量。它们不存在于b
之外且无法访问。它们只有在运行set_vals时才存在,之后它们会超出范围&#34; (已删除)。
答案 2 :(得分:1)
我觉得范围还可以。 在第一个示例中,您定义了方法(ok_then和sure)。这些都在模块范围内。在帽子之后你将变量&#34;设置为&#34;那些方法。方法仍在模块范围内。因此,同一范围(模块)中的每个方法都可以读取它们。
在另一个例子中,您可以在方法范围内定义变量&#34; set_val&#34;。所以其他所有方法都无法读取它们。