3 回答
TA贡献1860条经验 获得超9个赞
这就是闭包的工作方式。定义函数时output_after,它将text="hi there"在此函数的变量范围内使用变量。并且只能在函数内部更改此变量。
但是,如果要使用全局变量,则需要使用global构造:
def output_after():
global text, num
print "after change: object text " ,p.var
print "after change: object number ", p.num
print "after change: basic text " ,text
print "after change: basic num ", num
众所周知,Python中的所有变量名称都被称为对值的引用。因此,当我们定义函数时,我们将output_after复制所有当前上下文(对text,num,p对象的引用)。您可以使用id功能检查对对象的引用。当您更改文本和num的值时,引用将被更改,但是对于对象p将会相同。
请检查以下内容:
def change():
print(id(text))
text = "whats up"
print(id(text))
print(id(num))
num=5
print(id(text))
print(id(p))
p.num=10
print(id(p))
您可以看到num和text的引用已更改。
TA贡献1898条经验 获得超8个赞
简短答案:在函数外部或全局范围内声明的任何变量(意味着该变量不在任何类型的范围内,例如类,方法,条件语句等)都称为全局变量。
长调试的答案:
实际上,您的对象被声明为全局对象。
p=test()
p.var="good bye"
p.arr = []
p.num = 5
在上面的代码片段中,该p对象在方法范围之外进行了声明,从而允许所有对象都可以访问它。方法也在test类范围之外声明。实际上,没有什么阻止他们访问它。如果要更好地理解调试,请将p对象移至其中一种方法中,例如:
def output_before():
p=test()
p.var="good bye"
p.arr = []
p.num = 5
print "before change: object text " ,p.var
print "before change: object number ", p.num
print "before change: basic text " ,text
print "before change: basic num ", num
并重新运行您的代码,将产生:
before change: object text good bye
before change: object number 5
before change: basic text hi there
before change: basic num 1
然后出现以下错误:
追溯(最近一次呼叫最近):change()中的文件“ t.py”,第35行,更改中的文件“ t.py”,第29行,p.num = 10 NameError:未定义全局名称“ p”
但是,如果要从模块或方法内部访问对象,则可以使用关键字global,并且如文档所建议的那样:
这是因为当您对作用域中的变量进行赋值时,该变量将成为该作用域的局部变量,并在外部作用域中隐藏任何类似命名的变量。由于foo中的最后一条语句为x分配了一个新值,因此编译器将其识别为局部变量。因此,当较早的打印x尝试打印未初始化的局部变量并导致错误时,可以通过将其声明为全局变量来访问外部作用域变量
TA贡献1895条经验 获得超7个赞
就像Python中的其他任何变量一样。该函数首先在本地名称空间中检查变量。由于未在函数内部定义对象,因此它将检查外部命名空间,即您实际定义其的全局命名空间。
对于变量num /文本,您使用num = 5在change()。这将创建一个名为的局部变量,num并为其分配5。它不会更改全局变量。如果要全局更改它,则可以使用global关键字:
def change():
global text,num
num = 5 #Global num is changed
添加回答
举报