Python 函数参数传递的困惑
由于没有系统的学习过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_value
和input_value
指向了不同的对象。所以变量one_value的值保持不变。
例子2中,变量one_list
和input_list
都指向同一个list对象:
注意list对象本身是可以改变的,向其加入一个元素不会重新创建对象,是直接在原对象添加新元素。因此调用test_func2()
后,该对象结构如下图:
one_list
和input_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 函数参数传递的困惑相关推荐
- Python函数参数传递:传值还是传引用
引子 首先来看一个列子: def change(val):val.append(100)val = ['T', 'Z', 'Y'] nums = [0, 1] change(nums) print(n ...
- Python: 函数参数传递机制
Python: 函数参数传递机制 Python函数参数由实参传递给形参的过程,是由参数传递机制来控制的,根据实际参数类型不同,函数参数传递方式分为值传递和引用传递(又称为地址传递). 值传递机制 所谓 ...
- Python函数参数传递
Python函数参数传递 一.前言 二.了解形式参数和实际参数 1.通过作用理解 2.通过比喻来理解形参和实参 三.位置参数 1.数量必须与定义时一致 2.位置必须与定义时一致 四.关键字参数 五.为 ...
- Python函数参数传递的几种形式
Python函数参数传递的几种形式 前言 位置传参 序列传参(单星号元组传参) 关键字传参 字典关键字传参(双星号字典传参) 混合传参 函数的缺省参数 结束 前言 莫听穿林打叶声,何妨吟啸且徐行.竹杖 ...
- python 函数参数传递 格式_Python学习6.1_函数参数及参数传递
大多数编程语言都绕不开一个名词,那就是--函数(function).而函数很重要的部分则是参数(arguments)的使用.Python的参数传递总体来说是根据位置,传递对应的参数.阐述如下: 1.位 ...
- Python 函数参数传递
前言 Python 的函数参数传递相对于 C++来说更加灵活,并且使用也很方便,这里做下简单的总结. 正文 实参和形参 实参:在调用函数时提供的函数参数称为实参. 形参:定义函数时,函数中的变量成为形 ...
- python 函数参数传递机制_Python函数参数传递机制(超级详细)
Python中,函数参数由实参传递给形参的过程,是由参数传递机制来控制的.通过学习<Python函数值传递和引用传递>一节我们知道,根据实际参数的类型不同,函数参数的传递方式分为值传递和引 ...
- (转载)Python函数参数传递机制(超级详细)
Python中,函数参数由实参传递给形参的过程,是由参数传递机制来控制的.根据实际参数的类型不同,函数参数的传递方式分为值传递和引用传递(又称为地址传递),本节将对这两种传递机制做深度剖析. Pyth ...
- python函数参数传递的两种方式_Python函数的参数传递方式
Python函数的参数传递方式 一.普通 def add(a,b): return a+b print(add(1,2)) #输出结果:3 二.可选参数 def myjoin(string,sep=' ...
- python函数参数传递机制_Python 学习笔记(一) 理解Python的函数传参机制
对于刚接触Python不久的新手,Python的函数传参机制往往会让人迷惑.学过C的同学都知道函数参数可以传值或者传地址.比如下面这段代码 点击(此处)折叠或打开 void func(int inpu ...
最新文章
- 【BZOJ2245】[SDOI2011]工作安排 拆边费用流
- leetcode算法题--可以形成最大正方形的矩形数目
- 打印九九口诀表(15)
- bio linux 创建_不断升级,Java之BIO、NIO、AIO的演变
- python逐个读取文件_在Python中多次读取同一文件
- Android Studio的配置问题——Intel HAXM is required to run this AVD,VT-x is disabled in BIOS;
- java重置_JAVA復制數組和重置數組大小
- WPF 控件库——仿制Windows10的进度条
- centos8 yum太慢_Yum 慢到无法忍受?那是因为你没有这么做
- java 2 图形设计卷i awt_java 2 图形设计卷i:awt
- 《Linux内核分析》第三周笔记 构造一个简单的Linux系统MenuOS
- JS图表工具 ---- Highcharts
- 20-2.系统启动和内核管理centos7(unit,systemctl,grub2-)
- 基于CarMaker的C-NCAP主动安全系统试验仿真(二)
- 【室内/外设计】天正T20V3.0软件安装教程
- 桌面版docker安装搭建
- linux d开头是什么文件夹,linux文件权限,p开头/d开头/l开头
- Nothing is impossble
- go区块链培训学习:密码学算法家族
- IT行业里的热门技术