小议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 相关文章推荐
20招让你的Python飞起来!
Sep 27 Python
python 系统调用的实例详解
Jul 11 Python
Python实现将一个正整数分解质因数的方法分析
Dec 14 Python
python+matplotlib实现礼盒柱状图实例代码
Jan 16 Python
Python爬虫框架Scrapy基本用法入门教程
Jul 26 Python
详解Python requests 超时和重试的方法
Dec 18 Python
python3模拟实现xshell远程执行liunx命令的方法
Jul 12 Python
解决安装python3.7.4报错Can''t connect to HTTPS URL because the SSL module is not available
Jul 31 Python
利用Pytorch实现简单的线性回归算法
Jan 15 Python
PyQt5 如何让界面和逻辑分离的方法
Mar 24 Python
Python中socket网络通信是干嘛的
May 27 Python
Opencv中cv2.floodFill算法的使用
Jun 18 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中计算中文字符串长度、截取中文字符串的函数代码
2011/08/09 PHP
php jq jquery getJSON跨域提交数据完整版
2013/09/13 PHP
zf框架的Filter过滤器使用示例
2014/03/13 PHP
php伪静态之APACHE篇
2014/06/02 PHP
JavaScript写的一个DIV 弹出网页对话框
2009/08/14 Javascript
javascript 数字格式化输出的实现代码
2013/12/10 Javascript
Node.js模拟浏览器文件上传示例
2014/03/26 Javascript
AngularJS HTML编译器介绍
2014/12/06 Javascript
Node.js 制作实时多人游戏框架
2015/01/08 Javascript
举例简介AngularJS的内部语言环境
2015/06/17 Javascript
Vue.js 和 MVVM 的注意事项
2016/11/07 Javascript
JavaScript微信定位功能实现方法
2016/11/29 Javascript
JS异步文件上传(兼容IE8+)
2017/04/02 Javascript
js 取消页面可以选中文字的功能方法
2018/01/02 Javascript
解决vue 绑定对象内点击事件失效问题
2018/09/05 Javascript
Vue+webpack实现懒加载过程解析
2020/02/17 Javascript
JavaScript设计模式--简单工厂模式定义与应用案例详解
2020/05/23 Javascript
JavaScript设计模式之策略模式实现原理详解
2020/05/29 Javascript
[01:10:27]DOTA2-DPC中国联赛正赛 SAG vs XG BO3 第二场 3月5日
2021/03/11 DOTA
Python实现基于SVM的分类器的方法
2019/07/19 Python
python多线程并发及测试框架案例
2019/10/15 Python
wxPython绘图模块wxPyPlot实现数据可视化
2019/11/19 Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
2020/02/26 Python
Python面向对象程序设计之类和对象、实例变量、类变量用法分析
2020/03/23 Python
Tensorflow实现将标签变为one-hot形式
2020/05/22 Python
Elasticsearch py客户端库安装及使用方法解析
2020/09/14 Python
雅诗兰黛旗下走天然植物路线的彩妆品牌:Prescriptives
2016/08/14 全球购物
Vince官网:全球著名设计师品牌,休闲而优雅的服饰
2017/01/15 全球购物
美国汽车性能部件和赛车零件网站:Vivid Racing
2018/03/27 全球购物
Moss Bros官网:英国排名第一的西装店
2020/02/26 全球购物
别名指示符是什么
2012/10/08 面试题
网络事业创业计划书范文
2014/01/09 职场文书
新闻编辑专业毕业自荐书范文
2014/02/05 职场文书
2015年秋季新学期寄语
2015/03/25 职场文书
给学校的建议书400字
2015/09/14 职场文书
《水上飞机》教学反思
2016/02/20 职场文书