繁体   English   中英

基本的python,通过引用混淆传递[重复]

[英]Basic python, pass by reference confusion [duplicate]

这个问题已经在这里有了答案:

我不了解这两种方法之间的区别,有人可以解释吗? 为什么在其中一个中更改了参考对象,而在第二个中更改了参考? 如果有帮助,我来自Java,C#背景。 在我看来,这两个参考文献都应该更新。 谢谢

def changeme( mylist ):
   "This changes a passed list into this function"
   mylist.append([1,2,3,4]);
   print "Values inside the function: ", mylist
   return

# Now you can call changeme function
mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist

函数内部的值:[10、20、30,[1、2、3、4]]函数外部的值:[10、20、30,[1、2、3、4]

def changeme( mylist ):
    "This changes a passed list into this function"
   mylist = [1,2,3,4]; # This would assig new reference in mylist
   print "Values inside the function: ", mylist
   return

# Now you can call changeme function
mylist = [10,20,30];
changeme( mylist );
print "Values outside the function: ", mylist

函数内的值:[1、2、3、4]函数外的值:[10、20、30]

函数中的mylist = [1,2,3,4]更改参数mylist的值,该参数是函数外部对mylist的引用的副本 原始参考没有改变。

如果要修改列表(而不是对其的引用),请使用mylist[:] = [1,2,3,4]

这是您将要学习的关于Python的最重要的事情之一(嗯,这是对我来说)。

每个对象本质上都是未命名的,但是您可以将变量名绑定到该对象。

当您这样做时:

x = [1, 2, 3]

发生两件事:

  • 创建了[1, 2, 3] 对象
  • x名称已绑定到该名称。

这就是为什么当您更改对象时,所有绑定名称似乎都发生了变化:

>>> x = [1, 2, 3] ; y = x ; x ; y
[1, 2, 3]
[1, 2, 3]
>>> x.append(42) ; x ; y
[1, 2, 3, 42]
[1, 2, 3, 42]

在这种情况下,您没有更改xy ,而是这些变量后面更改了对象并且由于两个变量都绑定到该对象,因此两个变量都将受到影响。

因此,这如何影响您的问题。 当您将变量传递给函数时,函数定义中的名称与您传入的对象简单地绑定到同一对象:

def modList(x):      # 'x' and 'actual' now point to the SAME object.
    x.append(42)     # this will modify that object, no binding changes.
    x = [4, 5, 6]    # this will create NEW object and rebind 'x' to it.

actual = [1, 2, 3]   # object is [1, 2, 3], 'actual' is bound to it.
modList(actual)      # pass object reference to function.

因此,更改对象的语句(如modList的第一行)将对所有绑定进行更改,而重新绑定的语句(如第二行)将失去对原始对象的访问权限。

如果要使用看起来像赋值的语句更改对象,则可以使用数组切片进行更改。 之所以有效,是因为您要更改对象中的元素 ,而不是将x重新绑定到新对象:

x[:] = [4, 5, 6]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM