这个问题在这里已经有答案了:

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

有帮助吗?

解决方案

Python 按值传递对对象的引用.

Python按值(例如Java)传递对象的参考,而Python中的所有内容都是对象。这听起来很简单,但是您会注意到某些数据类型似乎显示出逐个价值的特征,而另一些数据类型似乎是通过引用的。这是怎么回事?

了解可变和不变的物体很重要。某些物体(例如字符串,元组和数字)是不变的。在函数/方法中更改它们将创建一个新实例,并且函数/方法之外的原始实例不会更改。其他对象(例如列表和词典)是可变的,这意味着您可以将对象更改为就位。因此,在函数/方法中更改对象也将在外部更改原始对象。

其他提示

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

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

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

func(myname) # calling the function

实际的对象是 myname 是指向已传递,而不是 姓名 myname 本身. 。函数内部 另一个名字 (x) 用来引用传递的同一对象。

如果对象是可变的,您可以修改函数内部的对象,但是您 无法更改外部名称所指向的内容. 。就像你这样做时发生的一样

anothername = myname

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

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

这里的答案很有帮助,但我发现有必要展示这种我没有看到的细微区别,我已经通过随后的 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]”包含在可变列表对象“list”中,而第一个示例中的“num”只是一个非包含的 Number 对象。

虽然本意是好的,但我觉得 @斯蒂芬·佩普 评价最高的答案(下面引用)和其他一些类似的答案并不完全正确(这促使我写下这个答案):

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

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

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

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

我还建议您查看 copy 模块:

Python文档复制

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

引用:

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


>>> foo(x)
>>> x
[1, 1, 2, 3]

请让我举一个简单的例子

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 a = b 28331264 a = b 28331264 a后b = x 28329344 a返回后,返回后28329344 28329344 var1 28329344 var1 283331264 var2 '6','7','8','9'

映射到存储器地址28329344 283331264 var1 var2 ab x a = b a = b a = b a后b = x b之后a [0] ='20'[0] ='[0] ='20'后'4'] ['20','6','7','8','9'

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top