您好,欢迎来到欧得旅游网。
搜索
您的当前位置:首页Python函数中修改变量(值传递、引用传递、可变对象、不可变对象)的深入思考

Python函数中修改变量(值传递、引用传递、可变对象、不可变对象)的深入思考

来源:欧得旅游网

在Python中,如果将数字、字符串等传入到函数中,再改变其值,我们会发现:当函数结束时,该变量不会发生改变。

In [20]: def q(x):
    ...:     x = 2
    ...:

In [21]: a = 1

In [22]: q(a)

In [23]: a
Out[23]: 1

我们先令a=1,再在函数中让a的值变为2,当函数结束时,打印a的值,依旧为1。有人称类似于a这样的变量为不可变对象(数字、字符、字符串、元祖等)

In [24]: def p(x):
    ...:     x[0] = 2
    ...:

In [25]: b = [1]

In [26]: p(b)

In [27]: b
Out[27]: [2]

这里我们令b是只有一个元素,且该元素值为1的列表,在函数中我们修改了b[0]的值,退出函数后发现b的值被修改了。有人称类似于b这样的变量为可变对象(列表、字典等)。

In [31]: def q(x):
    ...:     print(id(x))
    ...:     x = 2
    ...:     print(id(x))
    ...:
    ...:
    ...:

In [32]: a = 1

In [33]: id(a)
Out[33]: 2002568880

In [34]: q(a)
2002568880
2002568912

In [35]: id(a)
Out[35]: 2002568880
In [36]: id(1)
Out[36]: 2002568880

In [37]: c=1

In [38]: id(c)
Out[38]: 2002568880

那么,在函数中发生了什么?我将用下面的图来表示(用画图画的,有点丑):

所以我们退出函数时,a的值未发生改变。

同样的,我们对b进行分析。假设b是一个长度为100的列表,其中

In [60]: b[0] = 1

In [61]: b[1] = 2

In [62]: b[99] = 2
In [63]: id(b[0])
Out[63]: 2002568880

In [64]: id(b[1])
Out[64]: 2002568912

In [65]: id(b[99])
Out[65]: 2002568912

此时,定义一个函数p,修改b[99]的值

In [73]: def p(x):
    ...:     x[99] = 1
    ...:
    ...:

In [74]: b[99]
Out[74]: 2

In [75]: p(b)

In [76]: b[99]
Out[76]: 1

b[99]的值被修改了。

发生了什么?

在调用函数的过程中,首先生成x变量,指向了b指向的内存块。

再对x[99]赋值,指向了1所在的内存块

退出函数之后,x被丢弃,但b依然指向这个列表,而这个列表的内部元素已经被修改了。所以b[99]变成了1。

 

所以大家应该明白了,为什么数字、字符、字符串、元祖都是值传递,因为你传递进去生成了一个新的变量x,你修改x的值无非是修改了x指向的内存块,而对原变量没有影响。

如果你理解了上面,那么下面的情况你也应该理解了。

In [77]: def t(x):
    ...:     x = [55,66]
    ...:

In [78]: c = [1,2,3]

In [79]: t(c)

In [80]: c
Out[80]: [1, 2, 3]

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- ovod.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务