Python 变量范围(通过引用传递还是复制?) [英] Python Variable Scope (passing by reference or copy?)

查看:30
本文介绍了Python 变量范围(通过引用传递还是复制?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么变量 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 a list object somewhere in memory, the local variable L stores a reference to that object.
  • sorting (strictly speaking, the callable object pointed to be the global name sorting) gets called with a copy of the reference stored by L, and stores it in a local called x.
  • The method sort of the object pointed to by the reference contained in x is invoked. It gets a reference to the object (in the self 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆