小议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整型运算之布尔型、标准整型、长整型操作示例
Jul 21 Python
python编写Logistic逻辑回归
Dec 30 Python
浅谈python正则的常用方法 覆盖范围70%以上
Mar 14 Python
详解Python 函数如何重载?
Apr 23 Python
Python 20行简单实现有道在线翻译的详解
May 15 Python
matplotlib命令与格式之tick坐标轴日期格式(设置日期主副刻度)
Aug 06 Python
python 图片二值化处理(处理后为纯黑白的图片)
Nov 01 Python
Python遍历字典方式就实例详解
Dec 28 Python
运行tensorflow python程序,限制对GPU和CPU的占用操作
Feb 06 Python
使用Python合成图片的实现代码(图片添加个性化文本,图片上叠加其他图片)
Apr 30 Python
Python3开发环境搭建详细教程
Jun 18 Python
Python 利用flask搭建一个共享服务器的步骤
Dec 05 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 的ArrayAccess接口 像数组一样来访问你的PHP对象
2010/10/12 PHP
session在PHP大型web应用中的使用
2011/06/25 PHP
PHP测试程序运行时间的类
2012/02/05 PHP
关于js和php对url编码的处理方法
2014/03/04 PHP
Laravel最佳分割路由文件(routes.php)的方式
2016/08/04 PHP
Laravel接收前端ajax传来的数据的实例代码
2017/07/20 PHP
javascript addBookmark 加入收藏 多浏览器兼容
2009/08/15 Javascript
通过js动态操作table(新增,删除相关列信息)
2012/05/23 Javascript
js实时获取系统当前时间实例代码
2013/06/28 Javascript
JQuery插件开发示例代码
2013/11/06 Javascript
JQuery EasyUI 加载两次url的原因分析及解决方案
2014/08/18 Javascript
jQuery的load()方法及其回调函数用法实例
2015/03/25 Javascript
js验证身份证号有效性并提示对应信息
2015/10/19 Javascript
ES5学习教程之Array对象
2017/04/01 Javascript
快速解决bootstrap下拉菜单无法隐藏的问题
2018/08/10 Javascript
JavaScript this绑定过程深入详解
2018/12/07 Javascript
layui 弹出层值回传解决方式
2019/11/14 Javascript
[02:31]DOTA2帕克 英雄基础教程
2013/11/26 DOTA
Python中的高级数据结构详解
2015/03/27 Python
详解Python使用simplejson模块解析JSON的方法
2016/03/24 Python
Python运算符重载详解及实例代码
2017/03/07 Python
Python单体模式的几种常见实现方法详解
2017/07/28 Python
Python 实现淘宝秒杀的示例代码
2018/01/02 Python
浅析python的Lambda表达式
2019/02/27 Python
Django使用中间键实现csrf认证详解
2019/07/22 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
2020/04/08 Python
python cookie反爬处理的实现
2020/11/01 Python
css3绘制百度的小度熊
2018/10/29 HTML / CSS
巴西最大的珠宝连锁店:Vivara
2019/04/18 全球购物
体育教育专业自荐信范文
2013/12/20 职场文书
记者岗位职责
2014/01/06 职场文书
工作会议主持词
2014/03/17 职场文书
九九重阳节标语
2014/10/07 职场文书
实训报告范文大全
2014/11/04 职场文书
检讨书怎么写
2015/05/07 职场文书
力克胡哲观后感
2015/06/10 职场文书