Python 变量范围(通过引用传递还是复制?) [英] Python Variable Scope (passing by reference or copy?)
问题描述
为什么变量 L 在 sorting(L)
函数调用中被操作?在其他语言中,L 的副本将作为副本传递给 sorting()
,这样对 x
的任何更改都不会更改原始变量?
Why does the variable L gets manipulated in the sorting(L)
function call? In other languages, a copy of L would be passed through to sorting()
as a copy so that any changes to x
would not change the original variable?
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]
推荐答案
长话短说:Python 使用传值,但传值的是引用.实际的对象有 0 到无穷大的引用指向它们,为了改变该对象,无论您是谁以及您如何获得对对象的引用都无关紧要.
Long story short: Python uses pass-by-value, but the things that are passed by value are references. The actual objects have 0 to infinity references pointing at them, and for purposes of mutating that object, it doesn't matter who you are and how you got a reference to the object.
逐步完成您的示例:
L = [...]
在内存中的某处创建一个list
对象,局部变量L
存储对该对象的引用.sorting
(严格来说,指向全局名称sorting
的可调用对象)被L
存储的引用副本调用>,并将其存储在名为x
的本地.- 调用包含在
x
中的引用所指向的对象的方法sort
.它还获得对对象的引用(在self
参数中).它以某种方式改变了该对象(对象,而不是对该对象的一些引用,它不仅仅是一个内存地址). - 现在,由于引用被复制,而不是引用指向的对象,我们讨论的所有其他引用仍然指向同一个对象.就地"修改的一个对象.
testScope
然后返回对该列表对象的另一个引用.print
使用它来请求字符串表示(调用__str__
方法)并输出它.由于它仍然是同一个对象,当然它正在打印排序列表.
L = [...]
creates alist
object somewhere in memory, the local variableL
stores a reference to that object.sorting
(strictly speaking, the callable object pointed to be the global namesorting
) gets called with a copy of the reference stored byL
, and stores it in a local calledx
.- The method
sort
of the object pointed to by the reference contained inx
is invoked. It gets a reference to the object (in theself
parameter) as well. It somehow mutates that object (the object, not some reference to the object, which is merely more than a memory address). - Now, since references were copied, but not the object the references point to, all the other references we discussed still point to the same object. The one object that was modified "in-place".
testScope
then returns another reference to that list object.print
uses it to request a string representation (calls the__str__
method) and outputs it. Since it's still the same object, of course it's printing the sorted list.
因此,无论何时您将对象传递到任何地方,您都可以与接收它的人分享它.函数可以(但通常不会)改变它们传递的对象(由引用指向),从调用变异方法到分配成员.请注意,分配成员与分配普通的 ol 名称不同 - 这仅意味着改变您的本地范围,而不是任何调用者的对象.所以你不能改变调用者的本地变量(这就是它不是通过引用传递的原因).
So whenever you pass an object anywhere, you share it with whoever recives it. Functions can (but usually won't) mutate the objects (pointed to by the references) they are passed, from calling mutating methods to assigning members. Note though that assigning a member is different from assigning a plain ol' name - which merely means mutating your local scope, not any of the caller's objects. So you can't mutate the caller's locals (this is why it's not pass-by-reference).
进一步阅读:关于 effbot.org 的讨论为什么它没有通过-按引用,而不是大多数人所说的按值传递.
Further reading: A discussion on effbot.org why it's not pass-by-reference and not what most people would call pass-by-value.
这篇关于Python 变量范围(通过引用传递还是复制?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!