3

可能的重复:
了解 Python 传递函数参数的对象调用风格

我最近遇到了这个:

x = [1,2,3]

def change_1(x):
    x = x.remove(x[0])
    return x

结果是:

>>> change_1(x)
>>> x
[2, 3]

我发现这种行为令人惊讶,因为我认为函数内部的任何内容都不会影响外部变量。此外,我构建了一个示例,其中基本上做同样的事情但没有使用remove

x = [1,2,3]

def change_2(x):
    x = x[1:]
    return x

结果是:

>>> change_2(x)
[2, 3] # Also the output prints out here not sure why this is
>>> x
[1, 2, 3]

我得到了我期望的结果,函数不会改变 x。

所以它必须是remove有效果的特定的东西。这里发生了什么?

4

3 回答 3

7

令人困惑的一件事是您将许多不同的事物称为“x”。例如:

def change_1(x):       # the x parameter is a reference to the global 'x' list
    x = x.remove(x[0]) # on the left, though, is a new 'x' that is local to the function
    return x           # the local x is returned

>>> x = [1, 2, 3]
>>> y = change_1(x)    # assign the return value to 'y'
>>> print y
None                   # this is None because x.remove() assigned None to the local 'x' inside the function
>>> print x
[2, 3]                 # but x.remove() modified the global x inside the function

def change_2(x):
    x = x[1:]          # again, x on left is local, it gets a copy of the slice, but the 'x' parameter is not changed
    return x           # return the slice (copy)

>>> x = [1, 2, 3] 
>>> y = change_2(x)
>>> print x
[1, 2, 3]             # the global 'x' is not changed!
>>> print y
[2, 3]                # but the slice created in the function is assigned to 'y'
于 2012-04-23T03:04:12.527 回答
2

如果你调用你的函数的参数,你会得到同样的结果n,或者q

受影响的不是变量名。在x您的列表范围内和在x该范围之外是两个不同的“标签”。但是,由于您传递了x附加到的值,因此change_1()它们都指的是同一个对象。当您x.remove()对函数中的对象执行操作时,您基本上是在说:“获取x引用的对象。现在从该对象中删除一个元素。这与 lhs 分配非常不同。如果您y=0; x=y在函数内部执行了操作。您没有做列表对象的任何内容。您基本上只是撕下 of 的“x”标签[1, 2. 3]并将其放在 y 指向的任何内容上。

于 2012-04-23T02:33:26.167 回答
1

您的变量 x 只是对您创建的列表的引用。当您调用该函数时,您将按值传递该引用。但是在函数中,你有对同一个列表的引用所以当函数修改它时,它在任何范围内都被修改。

此外,在交互式解释器中执行命令时,python 会打印返回值,如果它没有分配给变量。

于 2012-04-23T02:30:12.777 回答