首先,我知道我可以使用global语句来访问全局变量。但不知何故,我能够在没有global的情况下修改全局列表,如下所示:
def func1(nums):
nums = [4,5,6]
nums = [1,2,3]
func1(nums)
print nums # print [1,2,3]
def func2(nums):
nums[0] = 4
nums[1] = 5
nums[2] = 6
nums = [1,2,3]
func2(nums)
print nums # print [4,5,6]在尝试func2之后,我意识到如果我指定索引,我总是可以在函数中访问全局列表:
def func3(nums):
nums[:] = [4,5,6]
nums = [1,2,3]
func3(nums)
print nums # print [4,5,6]是因为如果在定义之前使用了函数变量,Python会自动尝试匹配全局变量吗?
发布于 2015-07-16 01:42:27
我知道我可以使用global语句来访问全局变量
你的理解是错误的。只要没有同名的局部变量,就可以随时访问全局变量。只有当您要更改变量名所引用的对象时,才需要global语句。在您的func2中,您不会这样做;您只需要更改对象的内容。nums仍然引用相同的列表。
发布于 2015-07-16 00:35:00
它是基于Python中可变和不可变对象的概念。在您的示例中,例如:
a=[1,2]
def myfn():
a=[3,4]
print id(a)
>>>id(a)
3065250924L
>>>myfn()
3055359596很明显,两者是不同的对象。现在:
a=[1,2]
def myfn():
a[:] =[3,4]
print id(a)
>>>id(a)
3055358572
>>>myfn()
3055358572这意味着它是在局部和全局作用域中使用的相同变量。
发布于 2015-07-16 00:22:10
在这种情况下,这是因为list是可变的。
因此,将它们放在全局名称空间中,或者甚至通过函数传递,意味着它们将在Python持有对可变对象的引用时更改,而不是它的副本。
如果你用tuples做同样的事情,它不会起作用,因为它们是不可变的。
避免这种情况的方法是向函数提供列表的副本,而不是列表本身:
func2(list[:])同时,您可以使用默认参数来执行此操作,您可以将一个默认参数指定为[],如果您随后对其执行.append()操作,则该默认参数将在以后的所有调用中始终保留该项目(除非您以某种方式删除它)。
https://stackoverflow.com/questions/31435603
复制相似问题