基本的python,通过引用混淆

时间:2019-04-10 00:28:11

标签: python

我不了解这两种方法之间的区别,有人可以解释吗?为什么在其中一个中更改了参考对象,而在第二个中更改了参考?如果有帮助,我来自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]

2 个答案:

答案 0 :(得分:1)

函数中的

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

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

答案 1 :(得分:1)

这是您将要学习的关于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.

因此更改 object 的语句(如modList的第一行)将对所有绑定进行更改,而 rebind 的语句(如第二行) )将无法访问原始对象。

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

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