小议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错误和解决方法汇总整理
Jun 03 Python
Python实现批量转换文件编码的方法
Jul 28 Python
python生成器表达式和列表解析
Mar 10 Python
python中import学习备忘笔记
Jan 24 Python
pyhton列表转换为数组的实例
Apr 04 Python
python+opencv实现霍夫变换检测直线
Oct 23 Python
Python使用LDAP做用户认证的方法
Jun 20 Python
pandas 对日期类型数据的处理方法详解
Aug 08 Python
用Python绘制漫步图实例讲解
Feb 26 Python
基于Tensorflow的MNIST手写数字识别分类
Jun 17 Python
Python模拟登录requests.Session应用详解
Nov 17 Python
Python如何快速找到多个字典中的公共键(key)
Apr 29 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获取ip的三个属性区别介绍(HTTP_X_FORWARDED_FOR,HTTP_VIA,REMOTE_ADDR)
2012/09/23 PHP
php curl选项列表(超详细)
2013/07/01 PHP
php中Array2xml类实现数组转化成XML实例
2014/12/08 PHP
PHP实现批量上传单个文件
2015/12/29 PHP
PHP函数引用返回的实例详解
2016/09/11 PHP
PHP读取并输出XML文件数据的简单实现方法
2017/12/22 PHP
PHP实现腾讯短网址生成api接口实例
2020/12/08 PHP
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
Javascript解析URL方法详解
2014/12/05 Javascript
javascript动态添加删除tabs标签的方法
2015/07/06 Javascript
Javascript原型链的原理详解
2016/01/05 Javascript
js实现当鼠标移到表格上时显示这一格全部内容的代码
2016/06/12 Javascript
基于jQuery实现表格的查看修改删除
2016/08/01 Javascript
JS实现多物体运动的方法详解
2018/01/23 Javascript
JavaScript事件冒泡与事件捕获实例分析
2018/08/01 Javascript
快速解决vue在ios端下点击响应延时的问题
2018/08/27 Javascript
vue vue-Router默认hash模式修改为history需要做的修改详解
2018/09/13 Javascript
如何获取vue单文件自身源码路径
2019/05/06 Javascript
Vue使用虚拟dom进行渲染view的方法
2019/12/26 Javascript
如何使用RoughViz可视化Vue.js中的草绘图表
2021/01/30 Vue.js
python 网络爬虫初级实现代码
2016/02/27 Python
使用Python绘制图表大全总结
2017/02/11 Python
示例详解Python3 or Python2 两者之间的差异
2018/08/23 Python
python 将日期戳(五位数时间)转换为标准时间
2019/07/11 Python
在win64上使用bypy进行百度网盘文件上传功能
2020/01/02 Python
python安装dlib库报错问题及解决方法
2020/03/16 Python
python logging通过json文件配置的步骤
2020/04/27 Python
Python爬虫如何应对Cloudflare邮箱加密
2020/06/24 Python
Python csv文件记录流程代码解析
2020/07/16 Python
Philosophy美国官网:美国美容品牌
2016/08/15 全球购物
数控技术专业推荐信
2013/11/01 职场文书
建筑设计学生的自我评价
2014/01/16 职场文书
视光学专业自荐信
2014/06/24 职场文书
2015年度合同管理工作总结
2015/05/22 职场文书
Python爬虫之用Xpath获取关键标签实现自动评论盖楼抽奖(二)
2021/06/07 Python
Java 使用类型为Object的变量指向任意类型的对象
2022/04/13 Java/Android