我最近发现了一些我不希望使用python的东西,可以检查/访问在主范围内声明的函数内的变量,例如:
def my_func(mval):
print ("parameter:", mval)
print ("myvar:", myvar)
#myvar = "value" this is not allowed
print ("IN MAIN")
myvar = "123"
my_func(999)
输出:
IN MAIN
parameter: 999
myvar: 123
my_func
可以访问myvar
?然后为什么它失败了
试图改变价值? myvar
没有定义?我知道我们可以使用global
来完成这项工作,因为我们明确地说在我们想要访问的函数范围之外有一个变量,所以它会有意义。
我发现这很棘手,因为它可能会导致错误。
答案 0 :(得分:1)
myvar
处于全局范围内,因此无论您是否声明它都是全局的。读取时,python查看函数的本地作用域,然后回退到定义变量的模块全局作用域。写的时候,python有问题。它应该在本地函数范围还是全局范围内分配变量? global
关键字在函数中使用,并告诉该函数如何解决该问题。该变量从未被声明为全局变量,该函数被告知将该变量视为全局变量。
def my_func(mval):
global myval
myval = 'foo' # set in global scope
myval2 = 'bar' # set in local scope
答案 1 :(得分:1)
当您使用您提供的确切代码作为参考显示myvar
中my_func
的内容时,它将检查全局变量表以查看它是否先前在执行中定义,这就是为什么有用。然后,当您尝试通过取消注释myvar = "value"
在函数中为其分配值时,它会尝试将myvar
定义为my_func
的局部变量,这会隐藏对全局实例的引用myvar
。
我不确定使用global
关键字会导致任何问题,但它应该按预期工作。以下是如何使用它的示例:
def my_func(mval):
global myvar
print ("parameter:", mval)
print ("myvar:", myvar)
myvar = "value"
print ("IN MAIN")
myvar = "123"
my_func(999)
print("myvar after my_func:", myvar)
输出:
IN MAIN
parameter: 999
myvar: 123
myvar after my_func: value
如果您确实不想使用global
关键字,可以通过将myvar
作为my_func
的参数传递来获得所需的行为,并返回修改后的值以重新分配在主要范围内:
def my_func(mval, myvar):
print ("parameter:", mval)
print ("myvar:", myvar)
myvar = "value"
return myvar
print ("IN MAIN")
myvar = "123"
myvar = my_func(999, myvar)
print ("myvar after my_func:", myvar)
输出:
IN MAIN
parameter: 999
myvar: 123
myvar after my_func: value
如果已构建my_func
以返回值,请记住您可以在Python中返回多个值。因此,假设my_func
将返回名为returnvar
的变量,则上述代码可以写为:
def my_func(mval, myvar):
returnvar = mval + 1
print ("parameter:", mval)
print ("myvar:", myvar)
myvar = "value"
return myvar, returnvar
print ("IN MAIN")
myvar = "123"
myvar, returnvar = my_func(999, myvar)
print ("myvar after my_func:", myvar)
print ("returnvar:", returnvar)
输出:
IN MAIN
parameter: 999
myvar: 123
myvar after my_func: value
returnvar: 1000
答案 2 :(得分:0)
定义函数时,不仅针对语法评估其正确性,因此不会引发任何内容。一旦调用函数myvar
已在全局范围内定义,因此该函数有效。此外,如果您取消注释myvar = 'value'
my_func
,只要在调用函数之前定义myvar
,也会毫无例外地进行评估。