为什么python参数有时会改变?

cha*_*ghe 0 python python-2.7

这是我输入的代码.这里int的值没有在函数之外改变,但是list的值已经改变了.我期待list的值不会改变.是什么原因?

>>> def p1(list1):
    list1[0]=1000

>>> def p2(i):
    i+=10

>>> li=[1,2,3,4,5]
>>> int1=10
>>> p1(li)
>>> p2(int1)
>>> li
[1000, 2, 3, 4, 5]
>>> int1
10
Run Code Online (Sandbox Code Playgroud)

che*_*ner 5

请注意,在中p1,您没有为其分配值list1,该值是本地变量的名称p1.你实际上是分配给所述的第一个元素list对象引用list1,这是相同的list通过引用的对象li的封闭范围.

p2另一方面,In i+=10 确实为局部变量赋值i,而不是int1为封闭范围中的变量赋值.这是因为+=类型对象上的运算符int实际上并不修改对象,而是返回一个新对象.(也就是说,对于一个int,i+=10相当于i = i + 10.)


只是为了表明+= 可以直接对底层对象进行操作,请考虑以下函数:

def p3(list1):
    list1 += [10]
Run Code Online (Sandbox Code Playgroud)

然后在列表上运行它:

>>> foo = [1,2,3]
>>> p3(list1)
>>> foo
[1, 2, 3, 10]
Run Code Online (Sandbox Code Playgroud)

在这里,呼叫list1 += [10]实际上等同于list1.extend([10]),而不是list1 = list1 + [10]由于list.__iadd__定义的方式.在这里,您再次没有为名称赋值list1,而是在引用的对象上调用方法list1(引用的对象相同foo).

(更新:正如user2357112所指出的那样,从技术上讲,你可以分配给list1,但是list.__iadd__设计用于正确地分配相同的列表,这样最终结果就是你仍然可以引用你开始使用的同一个可变对象.)