在Python的范围内,函数/方法中的参数是通过值还是引用传递的?
我已经做了一些研究,有一个很好的资源:Are integers in Python passed by value or reference?
这个详细的一个可能是很好的参考,但它主要是关于整数。函数/方法参数的ti是怎样表示的?
我在命令行中做了一些测试/跟踪:
his_list = [1, 2, 3]
her_list = [4, 5, 6]
def change_list1(mylist):
mylist.append(100)
return mylist
def change_list2(mylist):
mylist = her_list
return mylist
test_list1 = change_list1(his_list)
test_list2 = change_list2(his_list)
print('test_list1: {}'.format(test_list1))
print('test_list2: {}'.format(test_list2))
print('his_list: {}'.format(his_list))
test_string = change_string(his_string)
print('test_string: {}'.format(test_string))
print('his_string: {}'.format(his_string))结果是:
test_list1: [1, 2, 3, 100]
test_list2: [4, 5, 6]
his_list: [1, 2, 3, 100]
test_string: abcdef
his_string: abc如果参数是通过引用传递的,为什么change_list2的结果似乎是通过值传递的?另外,当我将代码放在IDE中时,change_list2中的参数更改为灰色(意味着它的值未被使用)?
发布于 2018-09-28 04:19:45
Python按对象传递。在change_list1中,您传递一个可变对象并对其进行变异。它是同一个对象(一个列表),只是改变了(内容改变了)。mylist是引用对象的本地参数。函数返回原始对象。您会发现his_list也被修改了,因为它引用了同一个对象。
在change_list2中,您还传递一个可变对象,但不是对其进行变异,而是将一个新对象分配给本地参数。原始对象不变。函数返回新对象。
将Python中的变量仅仅看作对象的名称是很有帮助的。将参数传递给函数时,函数中参数的名称只是传递给函数的原始对象的新名称。
您可以通过打印传递给函数的对象名的ID和参数的对象名称的ID来看到这一点:
a = [1,2,3] # mutable object (content can be altered)
b = 1 # immutable object (content can't be altered).
print(f'id(a) = {id(a)}, id(b) = {id(b)}')
def func(c,d):
print('INSIDE func')
print(f'id(c) = {id(c)}, id(d) = {id(d)}')
c.append(4) # mutable object can be altered.
d = 4 # local name 'd' assigned a new object.
print('AFTER altering c & d')
print(f'id(c) = {id(c)}, id(d) = {id(d)}')
return c,d
e,f = func(a,b)
print('AFTER func called')
print(f'id(a) = {id(a)}, id(b) = {id(b)}')
print(f'id(e) = {id(e)}, id(f) = {id(f)}')
print(f'a = {a}, b = {b}')
print(f'e = {e}, f = {f}')输出:
id(a) = 2290226434440, id(b) = 1400925216
INSIDE func
id(c) = 2290226434440, id(d) = 1400925216
AFTER altering c & d
id(c) = 2290226434440, id(d) = 1400925312
AFTER func called
id(a) = 2290226434440, id(b) = 1400925216
id(e) = 2290226434440, id(f) = 1400925312
a = [1, 2, 3, 4], b = 1
e = [1, 2, 3, 4], f = 4注意,a和b的ID与参数名称c和d重合。名称指的是相同的对象。
c对象会发生变异。a引用相同的对象,因此将显示相同的更改。
d对象是不可变的。没有像.append这样的方法来改变对象的内容。d只能重新分配。它将被重新分配,并显示一个新的ID. b对象不变。
函数调用之后,e成为名为c (也称为a)的对象的新名称。名称c不再存在。这是一个本地函数名。f成为对象d (整数4)的新名称,d不再存在。b不受影响,并引用原始整数1。
a和e引用原始的、但经过变异的对象。b和f指不同的、不变的对象。
https://stackoverflow.com/questions/52548178
复制相似问题