问题:

在工作中发现在Python函数进行参数传递的时候,有的时候传递给函数的原始参数,会随着函数的修改而改变。有的时候却不会?就像下面这样:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def exchange_a(a):
    # 修改a
    a += 1
    print(f"函数修改后a: {a}")
    print(f"函数修改后a内存地址:{id(a)}")


def exchange_b(b):
    # 修改b
    b[1] = 20
    print(f"函数修改后b:{b}")
    print(f"函数修改后b内存地址:{id(b)}")


if __name__ == '__main__':
    a = 10
    exchange_a(a)
    print(f"原始参数a: {a}")
    print(f"原始参数a的内存地址: {id(a)}\n\n\n")

    b = [10, 20, 30, 40]
    exchange_b(b)
    print(f"原始参数b: {b}")
    print(f"原始参数b的内存地址:{id(b)}")

输入如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
函数修改后a: 11
函数修改后a内存地址:4398085776
原始参数a: 10
原始参数a的内存地址: 4398085744



函数修改后b:[10, 30, 30, 40]
函数修改后b内存地址:4405688136
原始参数b: [10, 30, 30, 40]
原始参数b的内存地址:4405688136

应该已经注意到了,我们函数a的没有改变原传递参数,而且修改后的内存地址也变了;函数b改变了原参数,并且内存地址没有变。

可以再试试string tuple 和 dict的区别 会发现结果是一样的。

这是为什么呢?


Python不允许程序员选择采用传值还是传引用。

正确的叫法应该是叫传对象或者说传对象引用。函数参数在传递过程中将整个对象传入,

对可变对象的修改在函数外部以及内部可见,可变对象:list dict

调用者和被调用者之间共享这个对象。而

对于不可变对象,由于并不能被真正被修改,因此,修改往往是通过生成一个新对象然后

赋值来实现。不可变对象:String Int Tuple

当我们在实际工作中要注意这点,在操作list 或者dict时,注意是否有被修改。必要时使用copy一份确保不会被修改