在Python中传递值[重复]

问题描述 投票:0回答:8

当你将像列表、数组这样的集合传递给Python中的另一个函数时,它会复制它,还是只是一个指针?

python pass-by-reference pass-by-value
8个回答
102
投票

Python 按值传递对对象的引用

Python 通过以下方式传递对象引用 值(如 Java),以及其中的所有内容 Python 是一个对象。这听起来 很简单,但是你会注意到 某些数据类型似乎表现出 按值传递特征,同时 其他人似乎表现得像 传递引用...有什么关系?

理解可变性很重要 和不可变的对象。一些物体, 就像字符串、元组和数字一样, 不可变的。在 a 内改变它们 函数/方法将创建一个新的 实例和原始实例 函数/方法之外不是 改变了。其他对象,例如列表 并且字典是可变的,这 意味着你可以改变对象 到位。因此,改变一个 函数/方法内的对象将 也改变原来的对象 外面。


84
投票

事实是,整个引用/值概念不适合Python。 Python 没有变量的“值”。 Python 只有对象和引用对象的名称。

因此,当您调用函数并在括号内放入“名称”时,如下所示:

def func(x): # defines a function that takes an argument
    ... # do something here

func(myname) # calling the function

传递的是

myname
指向的实际对象,而不是 name
myname
本身。在函数内部,给出了另一个名称x
)来引用传递的同一对象。 

如果函数内部的对象是可变的,您可以修改该对象,但是您

无法更改外部名称所指向的内容。与您这样做时发生的情况相同

anothername = myname

因此我可以回答你的问题:

它是“按值传递”,但所有值都只是对对象的引用。


28
投票
这里的答案很有帮助,但我发现有必要展示这种我没有看到的细微区别,我已经通过后续的 CL 实验向自己证明了这一点:

  1. 单独的不可变对象不能在函数调用中更改。(到目前为止的答案已经说了这么多......)
  2. 但是,包含在可变对象中的不可变对象可以在方法调用中重新分配。
'num' 在这里不会改变,因为它是一个不可变的 Number 对象 [支持我的观点 1。]:

>>> def incr_num(num): num += 1 >>> num = 0 >>> num 0 >>> incr_num(num) >>> num 0

list[0]

 这里也是一个不可变的 Number 对象。

>>> def incr_list(list): list[0] += 1 >>> list = [0] >>> list[0] 0 >>> incr_list(list) >>> list[0] 1

那么,作为一个不可变的 Number 对象,list[0]

 是如何改变的(支持我的观点 2),而上面示例的 Number 对象“num”却没有变化?
不可变的 Number 对象 list[0]
 包含在 
mutable 中列表对象“list”,而第一个示例中的“num”只是一个非包含的 Number 对象(immutable)。

虽然出发点是好的,但我觉得

@Stephen Pape最受好评的答案(下面引用),以及其他一些类似的答案,并不完全正确(这促使我写下这个答案):

有些对象,如字符串、元组和数字,是不可变的。 在函数/方法内更改它们将创建一个新实例并 函数/方法之外的原始实例没有改变。

我上面的第二个代码实验显示了一个 Number 对象('list[0]')在方法内被更改,然后函数外部的原始实例发生了更改。


9
投票
传递了一个引用,但如果参数是不可变对象,在方法内修改它将会创建一个新实例。


4
投票
对象已传递。不是副本,而是对底层对象的引用。


3
投票
参考:

>>> x = [0,1,2,3] >>> def foo(x_list): x_list[0] = 1 >>> foo(x) >>> x [1, 1, 2, 3]
    

3
投票
我还建议查看

copy

 模块:

Python文档复制

它将帮助您了解根本问题以及如何使用它来执行您自己的深层复制。


1
投票
请让我举一个简单的例子

def swap(a, b): x = a print id(x) print id(a) print id(b) a = b print id(a) b = x print id(b) a[0]= '20' var1 = ['1','2','3','4'] var2 = ['5','6','7','8','9'] print id(var1) print id(var2) swap(var1, var2) print id(var1) print id(var2) print var1 print var2
产生以下结果

28329344 var1 28331264 var2 28329344 x 28329344 a 28331264 b After a = b 28331264 a after b = x 28329344 b after return 28329344 var1 28331264 var2 ['1', '2', '3', '4'] ['20', '6', '7', '8', '9'] Mapping to the memory addresses 28329344 28331264 var1 var2 a b x After a=b a After b=x b After a[0] = '20' [0] = '20' After return ['1','2','3','4'] ['20', '6', '7', '8', '9']
    
© www.soinside.com 2019 - 2024. All rights reserved.