我对python中的全局变量有疑问。如果我正确理解了这一点,则可以从此类中的每个方法中读取在类中定义的所有变量。现在我以为只有在之前用全局'variableName'标记全局变量时,我才可以写入全局变量。但是,这让我很害怕:
def foo(a):
for i in range(a[0].__len__()):
a[0][i] -= a[1][i]
a = [[0,1,2,3,4,5,6],[0,1,2,3,4,5,6]]
foo(a)
print(a)
给我
[[0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6]]
但是为什么?我的意思是,我从未取消过'global a'。
奇怪的是,如果我这样做:
def foo(a):
a -= 1
a = 2
foo(a)
print(a)
这为什么给我
2
我不明白区别:/
您的函数定义有问题。您将两个函数都作为参数传递,因此不必首先声明全局变量。如果您要从定义中删除参数,那么这个问题会更有意义。
整个混乱在于python中数据类型的可变性。列表和字典是可变容器,这意味着它们的值可以随时更改。其他数据类型,例如整数,浮点数,元组等是不可变的。您无法更改它们。您可以创建一个新的整数,例如1 + 1
将返回一个新的整数2
。
在您的第一个示例中,您正在修改列表的内容。列表是可变容器,这意味着它们的内容可以更改。如果您碰巧在全局范围内有a
,则该范围内的函数可以修改列表的内容。
def foo():
""" Notice i've removed the argument `a` from the function def, to illustrate my point.. """
for i in range(a[0].__len__()):
a[0][i] -= a[1][i]
>>> a = [[0,1,2,3,4,5,6],[0,1,2,3,4,5,6]]
>>> foo()
>>> print(a)
[[0, 0, 0, 0, 0, 0, 0], [0, 1, 2, 3, 4, 5, 6]]
在第二个示例中,您正在修改整数。整数是不可变的数据类型,无法修改。以下will在函数a
的局部范围内修改变量foo()
(通过创建一个新的整数),但是由于您尚未全局定义a
或返回局部a
,因此看不到更改。
def foo(a):
a -= 1
>>> a = 2
>>> foo(a)
>>> print(a)
2
TL; DR global
与可变性无关。
您正在将列表作为参数a
传递给函数。列表是可变的,因此函数可以更改它。参数和全局变量都称为a
的事实并不重要:
def foo(some_list):
some_list.append('foo!')
global_list = []
foo(global_list)
print(global_list)
即使不直接引用['foo!']
,也打印foo
。您的代码中也发生了同样的事情。
现在更重要。修改全局变量:
global_list
还将修改def bar():
global_list.append('bar.')
,因为当它查找符号global_list
时,它将在模块(“全局”)范围内找到它。需要"global_list"
关键字的唯一情况是当您想重新绑定name global
时,因为in
global_list
该赋值隐式创建一个局部变量def reset():
global_list = []
,因此应将其写入
global_list