这保存在我的文件function_local.py
中:
x = 50
def func(x):
print('x is', x)
x = 2
print('Changed local x to', x)
func(x)
print('x is still', x)
输出:
$ python function_local.py
x is 50
Changed local x to 2
x is still 50
问题:当我们在函数内打印第一行时,为什么打印出50而不是2?即使在函数中说x = 2
?
答案 0 :(得分:3)
如果您在函数中分配变量名称(未声明global
或nonlocal
)或在函数的参数列表中使用变量名称,变量名称将成为功能的一部分。
在这种情况下,你可以在函数中使用任何变量名,因为它总是引用传入的局部变量:
x = 50
def func(another_x):
print('local x =', another_x)
another_x = 2
print('local x =', another_x)
return another_x
print('global x =', x)
x = func(x) # note that I assigned the returned value to "x" to make the change visible outside
print('global x =', x)
当我说x
与"将成为该功能的一部分时,我将尝试展示我的意思。
函数的__code__.co_varnames
包含函数的局部变量名称列表。因此,让我们看看在少数情况下会发生什么:
如果它是签名的一部分:
def func(x): # the name "x" is part of the argument list
pass
print(func.__code__.co_varnames)
# ('x',)
如果指定给变量(函数中的任何位置):
def func():
x = 2 # assignment to name "x" inside the function
print(func.__code__.co_varnames)
# ('x',)
如果您仅访问变量名称:
def func():
print(x)
print(func.__code__.co_varnames)
# ()
在这种情况下,它实际上会在外部作用域中查找变量名称,因为变量名x
不是函数varnames的一部分!
我可以理解这会让你感到困惑,因为只需在函数中的任何地方添加x=<whatever>
就可以使它成为函数的一部分:
def func():
print(x) # access
x = 2 # assignment
print(func.__code__.co_varnames)
# ('x',)
在这种情况下,赢了从外部范围查找变量x
,因为它现在是函数的一部分而且你会得到告诫异常(因为即使x
是函数的一部分,它也没有分配给但是):
>>> func()
UnboundLocalError: local variable 'x' referenced before assignment
显然,如果你在分配它后访问它会有效:
def func():
x = 2 # assignment
print(x) # access
或者如果你在调用函数时传递它:
def func(x): # x will be passed in
print(x) # access
关于局部变量名的另一个要点是你不能从外部作用域设置变量,除非你告诉Python明确地不使x
成为局部变量名的一部分,例如使用{{ 1}}或global
:
nonlocal
这实际上会覆盖调用def func():
global x # or "nonlocal x"
print(x)
x = 2
print(func.__code__.co_varnames)
# ()
时全局(或非本地)变量名x
所指的内容!
答案 1 :(得分:0)
在你的功能中
def func(x):
print('x is', x)
x = 2
print('Changed local x to', x)
x
不是全局变量;它是一个局部变量,因为在身体的第二行上赋值。如果要分配给全局变量,则必须将其显式声明为:
def func(x):
global x
print('x is', x)
x = 2
print('Changed local x to', x)
(注意:我错过了x
实际上是一个函数参数。有关本地名称赋值的说明不会影响全局名称,请参阅https://nedbatchelder.com/text/names.html。)
答案 2 :(得分:0)
这可以很容易理解。
x = 50
def func(x):
print "Local variables: "+str(locals())
print('x is', x)
x = 2
print "Local variables: "+str(locals())
print('Changed local x to', x)
func(x)
print('x is still', x)
和输出
Local variables: {'x': 50}
'x is', 50
Local variables: {'x': 2}
'Changed local x to', 2
'x is still', 50
但是,如果要在x
中定义x
之后想要从外部范围访问func
有一种方法,我不确定它是否会产生问题但是。
def func(x):
x = 2
print "local x == %s" % x
print "global x == %s" % globals().get('x')
func(x)
print "x is still %s" % x
以下将输出运行。
local x == 2
global x == 50
x is still 50