小议Python中自定义函数的可变参数的使用及注意点


Posted in Python onJune 21, 2016

可变参数

Python的可变参数有两种,一种是列表类型,一种是字典类型。列表类型类似 C 中的可变参数,定义方式为

def test_list_param(*args) :
  for arg in args :
    print arg

其中 args 是一个 tuple。
字典类型的可变参数:

def test_dict_param(**args) :
  for k, v in args.iteritems() :
    print k, v

其中 args 是一个 dictionary
可以分别传递 tuple 和 dictionary 给相应的可变参数,格式如下

a = (1, 2, 3)
b = {"a":1, "b":2, "msg":"hello"}
test_list_param(*a)
test_dict_param(**b)

带默认参数的函数

函数的带默认值参数能够很大程度上方便我们使用:一般情况下可以省略传参使用参数的默认值,也可以主动传参;调用的时候也不用在意参数的顺序方便使用,并且直接、显式;甚至还能用来当作魔法值,做一些逻辑上的控制。

但是由于python的默认值参数只会在函数定义处被解析一次,此后每次调用函数的时候,默认值参数都会是这个值了。碰到一些不可变的数据类型比如:整型,字符串,元祖之类的还好,但如果碰到可变类型的数据比如数组的话,就会有发生一些意想不到的事情。
让我们举一个简单的例子说明一下:

def add_to(num, target=[]):
  target.append(num)
  print id(target), target

add_to(1)
# Output: 39003656, [1]
add_to(2)
# Output: 39003656, [1, 2]
add_to(3)
# Output: 39003656, [1, 2, 3]

很显然如果你是想每次调用函数都能得到一个新的包含期望结果的数组,肯定不能如愿了。函数add_to的参数target在函数第一次被解析的时候会被赋值成空的数组,因为只会被解析一次,以后每次调用的时候都会在这个target变量的基础上进行操作,变量的id值也完全一样。想要得到预期的结果,可以为这种可变数据类型的参数指定一个None来表示空值:

a = (1, 2, 3)
b = {"a":1, "b":2, "msg":"hello"}
test_list_param(*a)
test_dict_param(**b)

在python的世界里,参数是按标识符传递(粗暴点解释就是按引用传递的),你需要担心的是参数的类型是否是可变的:

>>> def test(param1, param2):
...   print id(param1), id(param2)
...   param1 += 1
...   param2 += 1
...   print id(param1), id(param2)
...
>>> var1 = 1
>>> var2 = 2
>>> print id(var1), id(var2)
36862728 36862704
>>> test(var1, var2)
36862728 36862704
36862704 36862680

可变的数据类型,函数局部作用域里面的任何改变会保留在数据上;不可变的数据类型,发生的任何改变都只会体现在新生成的局部变量上,如同上面的列子中所示的效果,读者可以对比一下。

Python 相关文章推荐
简单介绍Python中用于求最小值的min()方法
May 15 Python
Python实现简单HTML表格解析的方法
Jun 15 Python
Django的URLconf中使用缺省视图参数的方法
Jul 18 Python
浅析Python中的多条件排序实现
Jun 07 Python
使用Django和Python创建Json response的方法
Mar 26 Python
Python实现检测文件MD5值的方法示例
Apr 11 Python
Python给图像添加噪声具体操作
Mar 03 Python
详解pandas的外部数据导入与常用方法
May 01 Python
关于python3中setup.py小概念解析
Aug 22 Python
实现Python与STM32通信方式
Dec 18 Python
基于h5py的使用及数据封装代码
Dec 26 Python
django使用channels实现通信的示例
Oct 19 Python
简单讲解Python编程中namedtuple类的用法
Jun 21 #Python
Python编程中实现迭代器的一些技巧小结
Jun 21 #Python
Centos Python2 升级到Python3的简单实现
Jun 21 #Python
Python的Django框架中forms表单类的使用方法详解
Jun 21 #Python
Python正则表达式使用经典实例
Jun 21 #Python
常见的python正则用法实例讲解
Jun 21 #Python
实例讲解Python的函数闭包使用中应注意的问题
Jun 20 #Python
You might like
超级简单的php+mysql留言本源码
2009/11/11 PHP
PHP弹出对话框技巧详细解读
2015/09/26 PHP
理解PHP中的Session及对Session有效期的控制
2016/01/08 PHP
ZendFramework2连接数据库操作实例
2017/04/18 PHP
PHP 构造函数和析构函数原理与用法分析
2020/04/21 PHP
js实现的网页颜色代码表全集
2007/07/17 Javascript
使用jQuery模板来展现json数据的代码
2010/10/22 Javascript
jquery.tmpl JQuery模板插件
2011/10/10 Javascript
jQuery循环滚动展示代码 可应用到文字和图片上
2012/05/11 Javascript
Js注册协议倒计时的小例子
2013/06/24 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
JavaScript中获取高度和宽度函数总结
2014/10/08 Javascript
javascript获取当前鼠标坐标的方法
2015/01/10 Javascript
详细解读JavaScript的跨浏览器事件处理
2015/08/12 Javascript
原生js获取iframe中dom元素--父子页面相互获取对方dom元素的方法
2016/08/05 Javascript
Vuejs第十三篇之组件——杂项
2016/09/09 Javascript
js判断出两个字符串最大子串的函数实现方法
2016/11/01 Javascript
关于Vue.js一些问题和思考学习笔记(1)
2016/12/02 Javascript
Bootstrap选项卡学习笔记分享
2017/02/13 Javascript
深入理解在JS中通过四种设置事件处理程序的方法
2017/03/02 Javascript
JS监听事件的叠加和移除功能
2018/11/19 Javascript
微信小程序实现炫酷的弹出式菜单特效
2019/01/28 Javascript
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
python3射线法判断点是否在多边形内
2019/06/28 Python
Python MySQLdb 执行sql语句时的参数传递方式
2020/03/04 Python
python实现从ftp上下载文件的实例方法
2020/07/19 Python
HTML5标签使用方法详解
2015/11/27 HTML / CSS
HTML5实现页面切换激活的PageVisibility API使用初探
2016/05/13 HTML / CSS
中国双语服务优势的在线购票及活动平台:247tickets
2018/10/26 全球购物
Feelunique德国官方网站:欧洲最大的在线美容零售商
2019/07/20 全球购物
介绍一下linux文件系统分配策略
2012/11/17 面试题
名人演讲稿范文
2013/12/28 职场文书
运动会解说词200字
2014/02/06 职场文书
2015年学校保卫部工作总结
2015/05/11 职场文书
校运会通讯稿
2015/07/18 职场文书
Redis的字符串是如何实现的
2021/10/24 Redis