小议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获取当前日期和时间的方法
Apr 30 Python
Python编程中的文件读写及相关的文件对象方法讲解
Jan 19 Python
Ubuntu下创建虚拟独立的Python环境全过程
Feb 10 Python
python3+PyQt5使用数据库表视图
Apr 24 Python
Python随机函数random()使用方法小结
Apr 29 Python
python爬虫之urllib3的使用示例
Jul 09 Python
纯用NumPy实现神经网络的示例代码
Oct 24 Python
Pycharm简单使用教程(入门小结)
Jul 04 Python
Python爬虫爬取Bilibili弹幕过程解析
Oct 10 Python
python创建子类的方法分析
Nov 28 Python
django数据模型中null和blank的区别说明
Sep 02 Python
Python破解极验滑动验证码详细步骤
May 21 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/05/18 PHP
php实现的zip文件内容比较类
2014/09/24 PHP
windows下配置php5.5开发环境及开发扩展
2014/12/25 PHP
元素的内联事件处理函数的特殊作用域在各浏览器中存在差异
2011/01/12 Javascript
Javascript中的isNaN函数使用说明
2011/11/10 Javascript
js 为label标签和div标签赋值的方法
2013/08/08 Javascript
js实现网页倒计时、网站已运行时间功能的代码3例
2014/04/14 Javascript
EasyUi中的Combogrid 实现分页和动态搜索远程数据
2016/04/01 Javascript
利用js编写响应式侧边栏
2016/09/17 Javascript
js利用appendChild对标签进行排序的实现方法
2016/10/16 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
yarn的使用与升级Node.js的方法详解
2017/06/04 Javascript
vue项目中锚点定位替代方式
2019/11/13 Javascript
[01:33]完美世界DOTA2联赛PWL S3 集锦第二期
2020/12/21 DOTA
python笔记(1) 关于我们应不应该继续学习python
2012/10/24 Python
Python 基础知识之字符串处理
2017/01/06 Python
python数据结构之链表详解
2017/09/12 Python
Python二叉树的镜像转换实现方法示例
2019/03/06 Python
python 弹窗提示警告框MessageBox的实例
2019/06/18 Python
python按比例随机切分数据的实现
2019/07/11 Python
基于多进程中APScheduler重复运行的解决方法
2019/07/22 Python
将python安装信息加入注册表的示例
2019/11/20 Python
Python Pickle 实现在同一个文件中序列化多个对象
2019/12/30 Python
python类共享变量操作
2020/09/03 Python
详解canvas在圆弧周围绘制文本的两种写法
2018/05/22 HTML / CSS
AmazeUI 等分网格的实现示例
2020/08/25 HTML / CSS
澳大利亚波西米亚风情网上商店:Czarina
2019/03/18 全球购物
Ootori在线按摩椅店:一家专业的按摩椅制造商
2019/04/10 全球购物
小学生安全教育广播稿
2014/10/20 职场文书
上班迟到检讨书
2015/05/06 职场文书
交通安全月活动总结
2015/05/08 职场文书
2015年科研工作总结范文
2015/05/13 职场文书
导游词之山东八大关
2019/12/18 职场文书
用Python进行栅格数据的分区统计和批量提取
2021/05/27 Python
Nginx动静分离配置实现与说明
2022/04/07 Servers
MySQL数据库之内置函数和自定义函数 function
2022/06/16 MySQL