为什么变量L在sorting(L)函数调用中被操纵?在其他语言中,L的副本将sorting()作为副本传递给任何更改,以便任何更改x都不会更改原始变量?
def sorting(x):
A = x #Passed by reference?
A.sort()
def testScope():
L = [5,4,3,2,1]
sorting(L) #Passed by reference?
return L
>>> print testScope()
>>> [1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
小智 15
长话短说:Python使用pass-by-value,但是通过值传递的东西是引用.实际对象有0到无穷大引用指向它们,并且为了改变该对象,无论你是谁以及如何获得对象的引用都无关紧要.
逐步完成您的示例:
L = [...]list在内存中的某个位置创建一个对象,局部变量L存储对该对象的引用.sorting(严格地说,可调用对象指向全局名称sorting)使用存储的引用副本进行调用L,并将其存储在本地调用的中x.sort包含在其中的引用指向的对象的方法x.它也获得对象(在self参数中)的引用.它以某种方式改变了该对象(对象,而不是对象的一些引用,它只是一个内存地址).testScope 然后返回对该列表对象的另一个引用.print使用它来请求字符串表示(调用__str__方法)并输出它.因为它仍然是同一个对象,当然它正在打印排序列表.因此,无论何时将对象传递到任何地方,都可以与任何人共享它.函数可以(但通常不会)改变它们传递的对象(由引用指向),从调用变异方法到赋值成员.请注意,分配成员与分配普通ol'名称不同 - 这仅仅意味着改变本地范围,而不是任何调用者的对象.所以你不能改变调用者的本地人(这就是为什么它不是传递参考).
进一步阅读:关于effbot.org的讨论为什么它不是通过参考而不是大多数人称之为按值传递的内容.
Python具有Mutable和Immutable对象的概念.像字符串或整数这样的对象是不可变的 - 您所做的每个更改都会创建一个新的字符串或整数.
列表是可变的,可以在适当的位置进行操作.见下文.
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print a is b, a is c
# False True
print a, b, c
# [1, 2, 3] [1, 2, 3] [1, 2, 3]
a.reverse()
print a, b, c
# [3, 2, 1] [1, 2, 3] [3, 2, 1]
print a is b, a is c
# False True
Run Code Online (Sandbox Code Playgroud)
注意c是如何反转的,因为c"是"a.有许多方法可以将列表复制到内存中的新对象.切片的简单方法是:c = a[:]