Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:修改函数内的全局列表_Python_Function_Global Variables - Fatal编程技术网

Python:修改函数内的全局列表

Python:修改函数内的全局列表,python,function,global-variables,Python,Function,Global Variables,首先,我知道我可以使用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) pri

首先,我知道我可以使用
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会自动尝试匹配全局变量吗?

在这种特定情况下,这是因为
list
s是可变的

因此,将它们放在全局名称空间中,甚至通过函数传递,意味着它们将随着Python持有对可变对象的引用而改变,而不是它的副本

如果您对
tuple
s尝试相同的操作,它将不起作用,因为它们是不可变的

避免这种情况的方法是向函数提供列表的副本,而不是列表本身:

func2(list[:])
同时,您可以使用默认参数执行此操作,您可以将默认参数指定为
[]
,如果您随后
.append()它的概念是基于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
这意味着它是在局部和全局范围内使用的同一个变量

我知道我可以使用全局语句访问全局变量

你的理解是错误的。只要没有同名的局部变量,就始终可以访问全局变量。当您要更改变量名所指的对象时,只需要
global
语句。在您的
函数2
中,您没有这样做;您只是在更改对象的内容<代码>nums仍然引用相同的列表。

  • 两个变量
    nums
    不同,它们指向同一个对象或两个不同的对象,尽管它们具有相同的名称
  • 当您调用
    func1(nums)
    时,表示您传递了一个引用。现在,两个变量
    nums
    指向同一个对象。(2个变量,1个对象)
  • func1
    中赋值时,内部变量
    nums
    将指向一个新对象,外部变量仍保持不变(2个变量,2个对象
  • 当您调用
    print nums
    时,这个
    nums
    是外部变量

这一结果有两个原因:

  • 变量只是引用对象的名称
  • 列表是可变的
  • func1
    中,
    nums
    引用一个新对象,因为创建了一个新列表。因此,
    全局NUM
    不受影响

    func2
    中,修改将应用于传入的对象。因此,
    全局nums
    发生了变化。未创建新对象,因为
    list
    是可变的


    ref:

    您的问题是什么
    nums=
    是一个本地赋值,与外部作用域无关,而在其他情况下,您修改的是同一个对象。这是否回答了您的问题?这与易变性无关。这是一个变异值与重新绑定变量值的问题。