python函数传参问题,一直没弄明白
天蓬老师
天蓬老师 2017-04-18 10:06:14
[Python讨论组]

python函数传参的时候,list作为可变对象,append之后,又给a重新赋值,为啥id是不同的?不是在原来的list上赋值吗?这块不明白..还有第二次打印的id和return回来的值的id差了个L是什么意思?

def setList(a):
    a.append(6)
    print id(a),a
    a = [8,9,0]
    print id(a),a
    return a
>>> s = [1,7,8]
>>> d = setList(s)
49420552 [1, 7, 8, 6]
49700360 [8, 9, 0]
>>> d
[8, 9, 0]
>>> id(d)
49700360L

--------------------------------------------分割线-----------------------------

>>> a = [1,2,3]
>>> id(a)
49420552L
>>> c = [1,2,3]
>>> id(c)
49390152L
>>> a=[1,2,3]
>>> id(a)
49352392L

我快被绕进去了。。。不是指向的同一段内存地址吗?怎么id不一样?

>>> a
[1, 2, 3]
>>> b

>>> b = [1,2,3]
>>> id(a)
49352392L
>>> id(b)
49374024L
>>> a == b
True

地址不一样。。。True又怎么解释。。。我要懵逼了。。

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回复(3)
ringa_lee

这个问题,你首先得理解什么是可变对象和不可变对象,在python中
数字,字符串和元组是不可变对象,列表,字典,字节数组是可变对象。那么怎么定义可变和不可变的呢?
就是根据值能否被改变。譬如我们定义一个元组,然后修改它

会发现修改的时候会报错,就是因为元组是不可变对象。

再来看字符串

发现修改同样会报错。因为字符串也是一个不可变对象

而对于数字,我们再来看看

并没有出错,这是因为在执行a=2的时候是在内存中重新创建一块内存来存放2,并将a的引用指向该内存。实际上a只是存放的是地址,而数字本身1或者2才是不可变对象。而不是a.它只是存的地址,对真实数字的引用。

对于你问题中,list是可变对象,但是你在函数中重新赋值了。这个时候改变了list对象的引用。所以id会不一样。下面你看另外一种情况,也许会更深你的理解, 看代码

首先我们定义了一个test方法,然后定义一个list类型变量a。 我们append了一个值后看它的id和append之前是一样的,这就是因为它是可变对象
它的值可以被修改。然后我们调用test方法。在方法里把a赋给了b。 然后b添加一个元素后。看输出可以发现原来的a也改变了。b 添加的10也体现在了a中。这是因为b=a这一步操作将a和b的引用指向同一个对象。所以b改变了,a也会改变。

而在你问题中,你setList方法中a = [8,9,0]操作相当于重新创建了一块内存,然后让a的引用指向它,所以你改变了a不会再改变原来列表的值

对于你下面的a = [1,2,3]和b=[1,2,3]为什么a == b 输出True ,这是因为==比较的是内容。如果你用is,is比较的是对象。你会发现输出False

迷茫

用代码+注释的方式回答这个问题吧:

def setList(a):
    # 下面是给传进来的类型为list的参数a添加一个元素
    a.append(6)
    print id(a),a
    # 下面是创建一个新的list:[8, 9, 0](这是个新的list,地址和之前的a不一样了),并把这个新的list返回给变量a
    a = [8,9,0]
    # 此时打印出来的地址就是新创建的那个list的地址,所以和以前不一样
    print id(a),a
    return a
# 打印出来相差一个“L”,id返回值是一个长整型,之所以有区别和具体展现实现有关,不用太介意
print id(a)
id(a)

-----------------分割线---------------

id值不一样:

  • 相同value的简单(immutable)变量,id一样,如:字符串,整型,tuple……

  • 相同value的复杂(mutable)变量,id不一样,如:dict,list,set……

>>> a = 1
>>> b =1
>>> id(a)
23880024
>>> id(b)
23880024
>>> a = '11'
>>> b = '11'
>>> a is b
True
>>> id(a)
140221799711648
>>> id(b)
140221799711648
>>> a = [1]
>>> b = [1]
>>> a is b
False
>>> id(a)
140221799558392
>>> id(b)
140221799557888
PHP中文网

因为你重新赋值了。。你了解指针的话就很好理解了。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号