小议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用fork来创建子进程注意事项
Jul 03 Python
Python循环语句之break与continue的用法
Oct 14 Python
Python2/3中urllib库的一些常见用法
Dec 19 Python
浅谈Series和DataFrame中的sort_index方法
Jun 07 Python
python实现名片管理系统
Nov 29 Python
详解django实现自定义manage命令的扩展
Aug 13 Python
Python 从attribute到property详解
Mar 05 Python
Python使用jupyter notebook查看ipynb文件过程解析
Jun 02 Python
浅析Python 条件控制语句
Jul 15 Python
Python钉钉报警及Zabbix集成钉钉报警的示例代码
Aug 17 Python
python里反向传播算法详解
Nov 22 Python
Python爬虫进阶之Beautiful Soup库详解
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高级OOP技术演示
2009/08/27 PHP
ThinkPHP控制器里javascript代码不能执行的解决方法
2014/11/22 PHP
PHP实现多图上传和单图上传功能
2018/05/17 PHP
关于javascript中的typeof和instanceof介绍
2012/12/04 Javascript
javascript打印html内容功能的方法示例
2013/11/28 Javascript
javascript内置对象arguments详解
2014/03/16 Javascript
原生JavaScript生成GUID的实现示例
2014/09/05 Javascript
javascript简单实现图片预加载
2014/12/03 Javascript
13 款最热门的 jQuery 图像 360 度旋转插件推荐
2014/12/09 Javascript
jQuery获取字符串中出现最多的数
2016/02/22 Javascript
Bootstrap4一次重大更新 几乎涉及每行代码
2016/05/16 Javascript
js获取隐藏元素宽高的实现方法
2016/05/19 Javascript
jQuery代码性能优化的10种方法
2016/06/21 Javascript
常用js,css文件统一加载方法(推荐) 并在加载之后调用回调函数
2016/09/23 Javascript
d3.js中冷门却实用的内置函数总结
2017/02/04 Javascript
Windows下快速搭建NodeJS本地服务器的步骤
2017/08/09 NodeJs
vue+Element-ui实现分页效果实例代码详解
2018/12/10 Javascript
微信小程序开发实现的IP地址查询功能示例
2019/03/28 Javascript
uni-app微信小程序登录授权的实现
2020/05/22 Javascript
使用vue实现通过变量动态拼接url
2020/07/22 Javascript
python从sqlite读取并显示数据的方法
2015/05/08 Python
基于wxpython实现的windows GUI程序实例
2015/05/30 Python
Python获取央视节目单的实现代码
2015/07/25 Python
python面试题小结附答案实例代码
2019/04/11 Python
Python实现TCP通信的示例代码
2019/09/09 Python
Python爬虫爬取电影票房数据及图表展示操作示例
2020/03/27 Python
Python操作word文档插入图片和表格的实例演示
2020/10/25 Python
详解用 python-docx 创建浮动图片
2021/01/24 Python
重新定义牛仔布,100美元以下:Warp + Weft
2018/07/25 全球购物
阳光体育活动实施方案
2014/05/25 职场文书
单方离婚协议书范本(2014版)
2014/09/30 职场文书
党的群众路线教育实践活动总结
2014/10/30 职场文书
2015年教师党员承诺书
2015/04/27 职场文书
莫言诺贝尔获奖感言(全文)
2015/07/31 职场文书
企业财务管理制度范本
2015/08/04 职场文书
化验室安全管理制度
2015/08/06 职场文书