Python学习之参数(一)

文章目录

  • Python学习之参数(一)
    • 参数的传递
    • 避免可变参数的修改
    • 参考资料

参数的传递

所有的参数实际上都是通过指针进行传递的。作为参数被传递的对象从来不自动拷贝。

在函数内部的参数名的赋值不会影响调用者。

如果传入的是可变对象,那么在函数内就可以就地改变这个可变对象,这可能会影响调用者。

Python通过赋值进行传递的机制与C++的引用参数选项并不完全相同,实际上它与C语言的参数传递模型相当相似。

不可变参数“通过值”进行传递。像整数和字符串这样的对象是通过对象引用而不是拷贝进行传递的,但是因为你无论怎样都不可能在原处改变不可变对象,所以实际效果就像创建了一份拷贝。

可变对象是通过指针进行传递的。例如,像列表和字典这样的对象也是通过对象引用进行传递的,这一点与C语言使用指针传递数组很相似:可变对象能够在函数内部进行原处改变,这一点和C数组很像。

以上只是偏重于理论的叙述,如果想搞清楚Python的参数传递机制,恐怕要研究几个例子。

考虑如下代码:

>>> def f(a):                 # a is assigned to (references) the passed objecta = 99                # Changes local variable a only
>>> b = 88
>>> f(b)                      # a and b both reference same 88 initially
>>> print(b)                  # b is not changed
88

第3行,b引用了88,可以认为b指向了88;

第4行,调用函数f,把b传了进去,实际上传递的是一个指针;

第1行,这里的a拥有了b的值,实际上是a也指向88;

第2行,a又指向了99;

第5行,打印b,此时b已然指向88,所以结果是88。

咱们再看一个例子。

>>> def changer(a, b):        # Arguments assigned references to objectsa = 2                 # Changes local name's value onlyb[0] = 'spam'         # Changes shared object in place
>>> X = 1
>>> L = [1, 2]                # Caller:
>>> changer(X, L)             # Pass immutable and mutable objects
>>> X, L                      # X is unchanged, L is different!
(1, ['spam', 2])

从第8行的结果来看,X 并没有改变,但是 L 从 [1, 2] 改变为 [‘spam’, 2]

X 没有改变,这和第一个例子是同样的道理。

我们分析一下 L 为什么会改变。第1行的b也是一个本地变量,但是一个可变对象传给了它——b指向了一个列表,它和L共享同一个对象。第3行,对b[0]进行赋值的结果会在函数返回后影响L的值。

下图中说明了函数调用前和调用中变量名与对象的绑定关系。

在调用changer函数之前,X 指向 1,L 指向列表 [1, 2] ;在函数调用的时候,X的值(对象1的地址)被传递给 a,所以 a 也指向1,同理,b 指向列表 [1, 2] ;因为 1 是不可变对象,所以 a = 2 并不会修改对象 1,而是使 a 指向 2,但是列表是可变对象, b[0] = ‘spam’ 确实修改了列表 [1, 2] ,使其变成了 [‘spam’, 2]。

如果上面的内容依然令你困惑的话,你可以这么理解,通过函数调用进行参数赋值与运行下面一系列简单的赋值语句是等效的:

>>> X = 1
>>> a = X               # They share the same object
>>> a = 2               # Resets 'a' only, 'X' is still 1
>>> print(X)
1
>>> L = [1, 2]
>>> b = L               # They share the same object
>>> b[0] = 'spam'       # In-place change: 'L' sees the change too
>>> print(L)
['spam', 2]

避免可变参数的修改

对可变参数的原处修改的行为不是一个 bug——它只是参数传递在Python中的工作方式。在Python中,默认通过引用(也就是指针)进行参数传递,因为这通常是我们想要的。这意味着不需要创建多个拷贝就可以传递很大的对象,并且能够按照需要方便地更新这些对象。

如果不想要函数内部在原处的修改影响到传递给他的对象,那么可以创建一个原对象的拷贝。例如:

L = [1, 2]
changer(X, L[:])        #通过切片传递拷贝,所以L不会改变

如果不想改变传入的对象,无论函数是如何调用的,我们同样可以在函数内部进行拷贝。

def changer(a, b):b = b[:]            # Copy input list so we don't impact callera = 2b[0] = 'spam'       # Changes our list copy only

—未完待续—

参考资料

《Python学习手册(第4版)》,机械工业出版社

《Learning Python 5th Edition》, O’Reilly

Python学习之参数(一)相关推荐

  1. 参数匹配顺序——Python学习之参数(三)

    参数匹配顺序--Python学习之参数(三) 文章目录 参数匹配顺序--Python学习之参数(三) 函数参数匹配表 参数匹配顺序 keyword-only 参数的位置 参考资料 这篇博文是对上一篇博 ...

  2. 参数匹配模型——Python学习之参数(二)

    参数匹配模型--Python学习之参数(二) 文章目录 参数匹配模型--Python学习之参数(二) 位置参数:从左至右进行匹配 关键字参数:通过参数名进行匹配 默认参数:为没有传入值的参数定义参数值 ...

  3. python学习——非参数密度估计

    代码:非参数密度估计的三种python实现 (直方图,核密度估计,K近邻) https://blog.csdn.net/weixin_42388833/article/details/11763228 ...

  4. 从0开始的Python学习009参数

    默认参数 对于参数有时候我们希望他是可选的,前面介绍了函数柯里化,当然还有其他的解决方案.如果不想给某些参数提供值的话,就让这写参数使用默认值.在函数定义的时候给参数赋值使用(参数,参数=值..... ...

  5. python学习——超参数调参工具optuna

    感觉目前是适配于各种框架,机器学习框架,深度学习框架,都比较好用的一个调参框架 参考文献:1.https://github.com/optuna/optuna-examples 2.https://z ...

  6. urlencode与params_qs Python学习笔记

    Python学习笔记 参数解码与编码. urlencode (编码) urlencode是一个函数,可将字符串以URL编码,用于编码处理. URL编码(URL encoding),也称作百分号编码(P ...

  7. [python教程入门学习]python学习笔记(CMD执行文件并传入参数)

    本文章向大家介绍python学习笔记(CMD执行文件并传入参数),主要包括python学习笔记(CMD执行文件并传入参数)使用实例.应用技巧.基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋 ...

  8. python学习笔记(14)参数对应

    python学习笔记(14)参数对应 原链:http://www.cnblogs.com/vamei/archive/2012/07/08/2581264.html 笔记: 1 #第14讲 2 #参数 ...

  9. Python学习:传递参数的多种方式

    Python中根据函数的输入参数以及是否有返回值可分为四种函数: 1.无参数无返回值 2.有参数无返回值 3.无参数有返回值 4.有参数无返回值 Python 中参数传递有下列五种方式; 1.位置传递 ...

最新文章

  1. 找Java培训机构有哪些评判标准
  2. OI模板のpoke流[大型考试复习必备/kl]
  3. c++ 传入动态参数_一文了解Mybatis中动态SQL的实现
  4. man命令的使用方法
  5. JavaScript 之 DOM中的三大对象
  6. 牛客多校第六场 G Is Today Friday? 蔡勒公式/排列
  7. Oracle数据库结构
  8. Electron下使用samba相关问题记录
  9. Python 3.9.5 官方中文文档及打包下载
  10. 计算机网络机房巡视表,机房巡查记录表.doc
  11. SM干货篇:你应该具备的提问技巧!
  12. 【力扣】735. 行星碰撞
  13. Gartner VPT技术原理 ——Tenable:专注于构成风险最大的漏洞
  14. java生气_Java来抢饭碗,C++可别生气
  15. 美国孩子上学真像你以为的那么轻松吗?
  16. uni-app插入ucharts(echarts)图表,支持H5,APP,小程序
  17. Java Web:开篇综述与第一章
  18. 逆向微信------给微信加上控件之骰子作弊
  19. 【光纤通信—第二部分 光源与光发送机】激光的产生与半导体激光器
  20. C#:Krypton控件使用方法详解(第八讲) ——kryptonBreadCrumb

热门文章

  1. NYOJ 586 疯牛
  2. 使用script命令自动录屏用户操作
  3. Mysql 连接查询
  4. 双目立体匹配经典算法之Semi-Global Matching(SGM)概述:匹配代价计算之互信息(Mutual Information,MI)...
  5. iOS源码学习总结框架
  6. 初学js----------一些API
  7. 利用栈将中缀表达式转化成后缀表达式
  8. Windows 8 动手实验系列教程 实验6:设置和首选项
  9. 两数之和C++代码实现超详细讲解
  10. web笔记Error:That IP address