打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
「20」如何避开Python函数的参数传递的各种坑(二)?

https://www.toutiao.com/i6755714650077135363/中已经讲述了何为函数的参数传递概念,以及传递可变对象的知识点。

此处要感谢一位条友指出的错误之处:元组是不可变对象!

本文要学习的就两个知识点:

1、函数传递不可变对象的引用;

2、不可变对象中是可以包含可变对象的。

不可变对象

在Python中的不可变对象包含int、Float、字符串、元组、布尔值等,但在函数传递参数时还是传递这些不可变对象的引用。特别之处是由于不可变对象无法修改,所以在进行“赋值操作”时,Python只能再创建一个新的对象。

我们以一个最简单的案例做分析:

# 传递不可变对象的引用x = 2019 # intdef test(n): print('赋值前n的ID为:',id(n)) # 赋值前的n n = n + 10 print('赋值后n的ID为:',id(n)) # 赋值后的n print(n)test(x)print('x的ID为:',id(x))

看看执行效果:

传递不可变对象引用案例

【结论】

  1. 全局变量X的ID在函数调用前后未发生变化,表示函数执行的参数传递确实是“引用传递”;
  2. 函数调用过程中的同一个变量名n在赋值语句执行前后的ID发生变化,表示确实在执行赋值过程中Python新建了一个对象,而不是修改传递参数的值。

不可变对象的可变对象

回忆学过的Python序列就知道元组(不可变对象)中是可以用列表(可变对象)作为元素的。这就很容易令我们产生一个问题:假如函数传递的参数不可变对象中包含了可变对象,但对可变对象进行赋值操作会有什么效果呢?

# 不可变对象中的可变对象s = (30,50,100,[40,20]) # 包含列表的元组print('被函数调用前s的ID为:',id(s))print('被函数调用前s的值为:',s)def test01(n): print('赋值前n的ID为:',id(n)) # 赋值前的n n[3][1] = 2019 print('赋值后n的ID为:',id(n)) # 赋值后的n print('赋值后n的值为:',n) # 赋值后的ntest01(s)print('被函数调用后s的ID为:',id(s))print('被函数调用后s的值为:',s)

执行效果:

不可变对象的可变对象

【结论】

  1. 不可变对象包含可变对象后还是可以作为函数参数使用;
  2. 不可变对象调用后的ID还是不变;
  3. 不可变对象中的可变对象在函数执行块中还是可以被修改值,并且Python不会再创建一个对象。

总结

初中物理知道“静止与运动是相对的”。在这里我也想用“变与不变都是相对的”来总结可变对象与不可变对象的关系。

在学习Python的过程中要有辩证的思维,在区分清楚不可变与可变的关系后,还要想到两者的关联关系。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
可变对象与不可变对象
深入理解python中函数传递参数是值传递还是引用传递
Python第二篇:数据结构列表、字典、元组、集合看这一篇完全够用
面试题-python 浅拷贝和深拷贝(copy模块)
Python进阶09 动态类型
函数1_Python
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服