由于没有系统的学习过Python,许多知识点都是破碎的,无法形成一个整体。总喜欢用其他语言来类比Python的语法。例如,对于参数传递,总觉得Python也会像C++那样分为值传递引用传递。无意间看到一篇博文,才发现其实区别很大。

首先,Python的函数参数传递,没有值传递和引用传递之分,因为根本没有引用传递的调用方式。

其次,就算都是值传递,Python的值传递也跟C++的值不一样。C++的值传递方式,实参的值是不会在函数调用之后有任何改变的,这点毫无疑问。而Python的值传递方式(这里姑且还是这样称呼它为值传递),实参在函数调用之后,可能不变,也可能改变,来看下面的例子:

# 例子1
def test_int(input_value):input_value = 2one_value = 1
test_int(one_value)
print('one_value = {}'.format(one_value))

例子1输出为:one_value = 1,例子1的输出很好理解,那下面的例子2呢?

# 例子2
def test_list(input_list):input_list.append(3)one_list = [1, 2]
test_list(one_list)
print('one_list = {}'.format(one_list))

例子2输出为:one_list = [1, 2, 3],为何结果会不一样呢?

其实,在 Python中,类型属于对象,变量是没有类型的,变量只是指向了对象:参数传递后,变量one_value和input_value都指向对象1,可以参考下面的贴图:

(2和3这些对象都是系统为了效率提前产生的)。由于test_int()函数体内要将变量input_value指向对象2,然后对象1不能直接转换成对象2(可以理解为常量对象),那么只能改变变量input_value的指向,使其指向对象2,那么整个对象结构就会变成如下形式:

因此,函数调用返回时,变量one_valueinput_value指向了不同的对象。所以变量one_value的值保持不变。

例子2中,变量one_listinput_list都指向同一个list对象:

注意list对象本身是可以改变的,向其加入一个元素不会重新创建对象,是直接在原对象添加新元素。因此调用test_func2()后,该对象结构如下图:

one_listinput_list依旧指向同一对象,改变input_list指向对象的值也就间接的改变了one_list的指向对象的值。

归根结底,函数调用后,如果形参转向指向另外的对象,形参的改变就不会影响到实参;如果形参的改变是直接在原指向对象上进行操作,形参实参任然都会指向同一对象,形参的改变就会同步到实参上。

或者说,函数的传参,应该分为不可变对象传递可变对象传递strings, set, tuples, numbers 是不可更改的对象,而list,dict等则是可以修改的对象。函数调用为不可变对象传递时,即使函数体中修改了形参,实参的值在函数调用返回时保持不变;如果函数调用为可变对象传递,函数体中修改了形参,实参的即会跟随发生改变。

弄懂了上面的原因,下面的情况也就很好理解了:

# 例子3
def test_tuple(input_tuple):input_tuple += (3, 4)one_tuple = (1, 2)
test_tuple(one_tuple)
print('one_tuple = {}'.format(one_tuple))

例子3的输出为one_tuple = (1, 2)

Python 函数参数传递的困惑相关推荐

  1. Python函数参数传递:传值还是传引用

    引子 首先来看一个列子: def change(val):val.append(100)val = ['T', 'Z', 'Y'] nums = [0, 1] change(nums) print(n ...

  2. Python: 函数参数传递机制

    Python: 函数参数传递机制 Python函数参数由实参传递给形参的过程,是由参数传递机制来控制的,根据实际参数类型不同,函数参数传递方式分为值传递和引用传递(又称为地址传递). 值传递机制 所谓 ...

  3. Python函数参数传递

    Python函数参数传递 一.前言 二.了解形式参数和实际参数 1.通过作用理解 2.通过比喻来理解形参和实参 三.位置参数 1.数量必须与定义时一致 2.位置必须与定义时一致 四.关键字参数 五.为 ...

  4. Python函数参数传递的几种形式

    Python函数参数传递的几种形式 前言 位置传参 序列传参(单星号元组传参) 关键字传参 字典关键字传参(双星号字典传参) 混合传参 函数的缺省参数 结束 前言 莫听穿林打叶声,何妨吟啸且徐行.竹杖 ...

  5. python 函数参数传递 格式_Python学习6.1_函数参数及参数传递

    大多数编程语言都绕不开一个名词,那就是--函数(function).而函数很重要的部分则是参数(arguments)的使用.Python的参数传递总体来说是根据位置,传递对应的参数.阐述如下: 1.位 ...

  6. Python 函数参数传递

    前言 Python 的函数参数传递相对于 C++来说更加灵活,并且使用也很方便,这里做下简单的总结. 正文 实参和形参 实参:在调用函数时提供的函数参数称为实参. 形参:定义函数时,函数中的变量成为形 ...

  7. python 函数参数传递机制_Python函数参数传递机制(超级详细)

    Python中,函数参数由实参传递给形参的过程,是由参数传递机制来控制的.通过学习<Python函数值传递和引用传递>一节我们知道,根据实际参数的类型不同,函数参数的传递方式分为值传递和引 ...

  8. (转载)Python函数参数传递机制(超级详细)

    Python中,函数参数由实参传递给形参的过程,是由参数传递机制来控制的.根据实际参数的类型不同,函数参数的传递方式分为值传递和引用传递(又称为地址传递),本节将对这两种传递机制做深度剖析. Pyth ...

  9. python函数参数传递的两种方式_Python函数的参数传递方式

    Python函数的参数传递方式 一.普通 def add(a,b): return a+b print(add(1,2)) #输出结果:3 二.可选参数 def myjoin(string,sep=' ...

  10. python函数参数传递机制_Python 学习笔记(一) 理解Python的函数传参机制

    对于刚接触Python不久的新手,Python的函数传参机制往往会让人迷惑.学过C的同学都知道函数参数可以传值或者传地址.比如下面这段代码 点击(此处)折叠或打开 void func(int inpu ...

最新文章

  1. 【BZOJ2245】[SDOI2011]工作安排 拆边费用流
  2. leetcode算法题--可以形成最大正方形的矩形数目
  3. 打印九九口诀表(15)
  4. bio linux 创建_不断升级,Java之BIO、NIO、AIO的演变
  5. python逐个读取文件_在Python中多次读取同一文件
  6. Android Studio的配置问题——Intel HAXM is required to run this AVD,VT-x is disabled in BIOS;
  7. java重置_JAVA復制數組和重置數組大小
  8. WPF 控件库——仿制Windows10的进度条
  9. centos8 yum太慢_Yum 慢到无法忍受?那是因为你没有这么做
  10. java 2 图形设计卷i awt_java 2 图形设计卷i:awt
  11. 《Linux内核分析》第三周笔记 构造一个简单的Linux系统MenuOS
  12. JS图表工具 ---- Highcharts
  13. 20-2.系统启动和内核管理centos7(unit,systemctl,grub2-)
  14. 基于CarMaker的C-NCAP主动安全系统试验仿真(二)
  15. 【室内/外设计】天正T20V3.0软件安装教程
  16. 桌面版docker安装搭建
  17. linux d开头是什么文件夹,linux文件权限,p开头/d开头/l开头
  18. Nothing is impossble
  19. go区块链培训学习:密码学算法家族
  20. IT行业里的热门技术

热门文章

  1. 基于SWT的Sash和FormLayout的自定义分隔窗体
  2. go中分析工具:pprof
  3. 【转载】Python tips: 什么是*args和**kwargs?
  4. Redis数据类型及使用场景
  5. 陈桂林个人博客传送门
  6. NGUI的拖拽和放下功能的制作,简易背包系统功能(drag and drop item)
  7. SQLServer 使用sp_repldone标识所有未分发的事务为已分发
  8. 简化版shell远程登录脚本
  9. RAD 版本迁移工具,不怕升级麻烦了。
  10. struts2自己定义拦截器