对象的引用。为什么这个变量会改变?

时间:2014-04-16 21:34:23

标签: python

以下代码:

#!/usr/bin/python

class Test():
def __init__(self):
    self.myList = [i for i in range(10)]

def method(self, val, num):
    for i in range(10):
        if i < val:
            self.myList[i] = num

inst = Test()

before = inst.myList
print 'before = ', before
inst.method(4, 6)
print 'after = ', inst.myList
print ' '

inst.myList = before
print 'before = ', before
inst.method(2, 4)
print 'before = ', before
print 'after = ', inst.myList`

输出:

before =  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
after =  [6, 6, 6, 6, 4, 5, 6, 7, 8, 9]

before =  [6, 6, 6, 6, 4, 5, 6, 7, 8, 9]
before =  [4, 4, 6, 6, 4, 5, 6, 7, 8, 9]
after =  [4, 4, 6, 6, 4, 5, 6, 7, 8, 9]

为什么在第二次调用method()之后,变量变量会发生变化?关于对象引用的东西?是因为inst.myList = before使它们都指向同一个列表,所以当我改变inst.myList时,之前也会改变吗?

另外,如果我用以下方法调用方法:

inst.method(2, 4)

这是否可以保证更改inst.myList以便以后在程序中使用?如果在方法中更改了?或者我需要在Test类中做这样的事情吗?

@staticmethod
def method(listtt, val, num):
    # do stuff to list
    return listtt

然后用:

调用它
inst.myList = Test.method(inst.myList, 2, 4)

我并不完全理解通过作业传递的内容以及什么是不可变的。如果它是第二个,那么如果我必须传递所有内容并且仍然返回所有内容,那么使用self是什么意思呢?为什么不只是拥有所有静态方法?

1 个答案:

答案 0 :(得分:3)

  

是因为inst.myList = before使它们都指向同一个列表,所以当我改变inst.myList时,之前也会改变吗?

是的,这正是原因。

至于inst.method是否“保证”更改inst.myList,这取决于您的意思。根据您提供的特定实现,是的,只要它是一个列表,就可以保证更改它,因为您使用了项目赋值(foo[bar] = baz语法),并且该语法会改变列表。但是当然你可以用不同的方式写inst.method,这样它就不会修改inst.myList,所以从这个意义上说它不是“保证”。