Python:按引用传递修改参数
Python: Pass by reference modifies the argument
我在Python中有这段代码:
def sortList(x):
x.sort()
print "Values inside the function: ", x
return
mylist = [100,20,30];
sortList(mylist);
print "Values outside the function: ", mylist
输出为:
Values inside the function: [20, 30, 100]
Values outside the function: [20, 30, 100]
现在,如果我写 x=[1,2,3]
而不是写 x.sort()
那么输出是:
Values inside the function: [1, 2, 3]
Values outside the function: [100, 20, 20]
那么为什么数组 "mylist" 的值会在函数内部发生变化?而且只有当我对其执行一些操作时才会出现这种情况,而不是当我为其分配全新的值时?
谢谢!
很简单:python 不是按值(即副本)传递参数,而是按引用传递参数。因此,在 sortList 内部,您操作的是您传入的同一个列表。由开发人员自行决定是否对此进行补救。一种方法是改用 sorted
调用,它会为您提供序列的排序副本。其他涉及使用 copy.copy
或 copy.deepcopy
因为参数是通过赋值传递的,参数名
在函数中可以与调用范围内的变量共享对象。因此,对函数中可变参数的就地更改会影响调用者。
并且在你的代码中第一次因为你使用 sort()
函数并且它改变了 x
就地,它影响调用者并全局改变 x!但是当你分配一个x
的新对象实际上您在引用新对象 ([1, 2, 3]
) 的函数内创建了一个局部变量。
因此,为了避免可变参数更改,您可以将变量的 copy 传递给函数:
mylist = [100,20,30];
sortList(mylist[:]);
print "Values outside the function: ", mylist
结果:
Values inside the function: [20, 30, 100]
Values outside the function: [100, 20, 30]
作为另一种方法,您可以将参数转换为不可变对象,更改它会引发错误,在这种情况下,您可以将列表转换为元组:
mylist = [100,20,30];
sortList(tuple(mylist));
print "Values outside the function: ", mylist
Traceback (most recent call last):
File "/home/bluebird/Desktop/try.py", line 7, in <module>
sortList(tuple(mylist));
File "/home/bluebird/Desktop/try.py", line 2, in sortList
x.sort()
AttributeError: 'tuple' object has no attribute 'sort'
您正在将一个对象值传递给您的函数,然后您正在修改该对象。这改变了对象。只有一个对象,Python 在将对象传递给函数时不会创建对象的独立副本。
现在,如果您将一个完全不同的对象分配给 变量 x
,这不会对之前在 [=10= 中的对象做任何事情].它只是打破了从 x
到该对象的引用。由于该对象仍被 mylist
引用,因此它继续存在。
我在Python中有这段代码:
def sortList(x):
x.sort()
print "Values inside the function: ", x
return
mylist = [100,20,30];
sortList(mylist);
print "Values outside the function: ", mylist
输出为:
Values inside the function: [20, 30, 100] Values outside the function: [20, 30, 100]
现在,如果我写 x=[1,2,3]
而不是写 x.sort()
那么输出是:
Values inside the function: [1, 2, 3] Values outside the function: [100, 20, 20]
那么为什么数组 "mylist" 的值会在函数内部发生变化?而且只有当我对其执行一些操作时才会出现这种情况,而不是当我为其分配全新的值时?
谢谢!
很简单:python 不是按值(即副本)传递参数,而是按引用传递参数。因此,在 sortList 内部,您操作的是您传入的同一个列表。由开发人员自行决定是否对此进行补救。一种方法是改用 sorted
调用,它会为您提供序列的排序副本。其他涉及使用 copy.copy
或 copy.deepcopy
因为参数是通过赋值传递的,参数名 在函数中可以与调用范围内的变量共享对象。因此,对函数中可变参数的就地更改会影响调用者。
并且在你的代码中第一次因为你使用 sort()
函数并且它改变了 x
就地,它影响调用者并全局改变 x!但是当你分配一个x
的新对象实际上您在引用新对象 ([1, 2, 3]
) 的函数内创建了一个局部变量。
因此,为了避免可变参数更改,您可以将变量的 copy 传递给函数:
mylist = [100,20,30];
sortList(mylist[:]);
print "Values outside the function: ", mylist
结果:
Values inside the function: [20, 30, 100]
Values outside the function: [100, 20, 30]
作为另一种方法,您可以将参数转换为不可变对象,更改它会引发错误,在这种情况下,您可以将列表转换为元组:
mylist = [100,20,30];
sortList(tuple(mylist));
print "Values outside the function: ", mylist
Traceback (most recent call last):
File "/home/bluebird/Desktop/try.py", line 7, in <module>
sortList(tuple(mylist));
File "/home/bluebird/Desktop/try.py", line 2, in sortList
x.sort()
AttributeError: 'tuple' object has no attribute 'sort'
您正在将一个对象值传递给您的函数,然后您正在修改该对象。这改变了对象。只有一个对象,Python 在将对象传递给函数时不会创建对象的独立副本。
现在,如果您将一个完全不同的对象分配给 变量 x
,这不会对之前在 [=10= 中的对象做任何事情].它只是打破了从 x
到该对象的引用。由于该对象仍被 mylist
引用,因此它继续存在。