在 Python 中传递值[重复]
- 2025-01-20 09:07:00
- admin 原创
- 123
问题描述:
当您将列表、数组等集合传递给 Python 中的另一个函数时,它会复制它,还是仅仅是一个指针?
解决方案 1:
Python通过值传递对象的引用。
Python 通过值传递引用到对象(就像 Java 一样),Python 中的一切都是对象。这听起来很简单,但随后您会注意到,某些数据类型似乎表现出按值传递的特性,而其他数据类型似乎表现得像按引用传递... 这是怎么回事?
了解可变和不可变对象非常重要。有些对象(如字符串、元组和数字)是不可变的。在函数/方法内部更改它们将创建一个新实例,而函数/方法外部的原始实例不会更改。其他对象(如列表和字典)是可变的,这意味着您可以就地更改对象。因此,在函数/方法内部更改对象也会更改外部的原始对象。
解决方案 2:
问题是,整个引用/值概念不适合 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
因此我可以这样回答你的问题:
它是“按值传递”,但所有值都只是对对象的引用。
解决方案 3:
这里的答案很有帮助,但我发现有必要展示这种我还没有看到过的细微区别,我已经通过随后的 CL 实验向自己证明了这一点:
不可变对象本身无法在函数调用中被改变。(到目前为止的答案已经说了很多......)
但是,包含在可变对象中的不可变对象可以在方法调用中重新分配。
'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
list[0]
那么,作为一个不可变的 Number 对象,它是如何变化的(支持我的观点 2.),而上面例子中的 Number 对象 'num' 没有变化? 不可变的 Number 对象list[0]
包含在可变列表对象 'list' 中,而第一个例子里的 'num' 只是一个非包含的 Number 对象(不可变)。
尽管用意是好的,但我觉得@Stephen Pape最受好评的答案(下面引用)和其他一些类似的答案并不完全正确(这促使我写下这个答案):
有些对象(如字符串、元组和数字)是不可变的。在函数/方法内部更改它们将创建一个新实例,而函数/方法外部的原始实例不会改变。
上面的第二个代码实验显示了一个 Number 对象 ('list[0]') 在方法内被改变,然后函数外的原始实例也发生了改变。
解决方案 4:
传递了一个引用,但如果参数是不可变对象,则在方法内修改它将创建一个新实例。
解决方案 5:
传递了对象。不是副本,而是对底层对象的引用。
解决方案 6:
参考:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
解决方案 7:
我还建议看一下模块copy
:
复制的 Python 文档
它将帮助您了解底层问题以及如何使用它来执行您自己的深度复制。
解决方案 8:
请让我举一个简单的例子
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']
扫码咨询,免费领取项目管理大礼包!