小议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利用pyHook实现监听用户鼠标与键盘事件
Aug 21 Python
Python日志模块logging简介
Apr 13 Python
利用Python脚本生成sitemap.xml的实现方法
Jan 31 Python
python利用lxml读写xml格式的文件
Aug 10 Python
利用信号如何监控Django模型对象字段值的变化详解
Nov 27 Python
python代码实现ID3决策树算法
Dec 20 Python
python实现一个简单的并查集的示例代码
Mar 19 Python
Python通过属性手段实现只允许调用一次的示例讲解
Apr 21 Python
解决python执行不输出系统命令弹框的问题
Jun 24 Python
PyQt 图解Qt Designer工具的使用方法
Aug 06 Python
Python数据可视化常用4大绘图库原理详解
Oct 23 Python
Python中的pprint模块
Nov 27 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 反向排序和随机排序代码
2010/06/30 PHP
php array_filter除去数组中的空字符元素
2020/06/21 PHP
php源码分析之DZX1.5字符串截断函数cutstr用法
2015/06/17 PHP
laravel 根据不同组织加载不同视图的实现
2019/10/14 PHP
确保Laravel网站不会被嵌入到其他站点中的方法
2019/10/18 PHP
基于JQuery 选择器使用说明介绍
2013/04/18 Javascript
浅谈Jquery为元素绑定事件
2015/04/27 Javascript
jQuery实现复选框批量选择与反选的方法
2015/06/17 Javascript
JavaScript多图片上传案例
2015/09/28 Javascript
JSP防止网页刷新重复提交数据的几种方法
2016/11/19 Javascript
微信小程序 实战实例开发流程详细介绍
2017/01/05 Javascript
canvas实现钟表效果
2017/02/13 Javascript
js实现自定义进度条效果
2017/03/15 Javascript
AngularJS遍历获取数组元素的方法示例
2017/11/11 Javascript
ES6之模版字符串的具体使用
2018/05/17 Javascript
详解JS函数stack size计算方法
2018/06/18 Javascript
layui+jquery支持IE8的表格分页方法
2019/09/28 jQuery
Vue中component标签解决项目组件化操作
2020/09/04 Javascript
用Eclipse写python程序
2018/02/10 Python
Python装饰器模式定义与用法分析
2018/08/06 Python
对numpy中的where方法嵌套使用详解
2018/10/31 Python
Python 3.x基于Xml数据的Http请求方法
2018/12/28 Python
python3 property装饰器实现原理与用法示例
2019/05/15 Python
Python selenium模块实现定位过程解析
2020/07/09 Python
css3打造一款漂亮的卡哇伊按钮
2013/03/20 HTML / CSS
澳大利亚购买太阳镜和眼镜网站:Glamoureyes
2020/09/22 全球购物
如何将无状态会话Bean发布为WEB服务,只有无状态会话Bean可以发布为WEB服务?
2015/12/03 面试题
大学生村官任职感言
2014/01/09 职场文书
机关会计岗位职责
2014/04/08 职场文书
求职信范文大全
2014/05/26 职场文书
创先争优活动承诺书
2014/08/30 职场文书
个人向公司借款协议书
2014/10/09 职场文书
运动会加油稿20字
2014/11/15 职场文书
劳模先进事迹材料
2014/12/24 职场文书
2016年“我们的节日·重阳节”主题活动总结
2016/04/01 职场文书
springboot 自定义配置 解决Boolean属性不生效
2022/03/18 Java/Android