小议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获得图片base64编码示例
Jan 16 Python
Request的中断和ErrorHandler实例解析
Feb 12 Python
Python 经典面试题 21 道【不可错过】
Sep 21 Python
解决python "No module named pip" 的问题
Oct 13 Python
在Pycharm中项目解释器与环境变量的设置方法
Oct 29 Python
python3正则提取字符串里的中文实例
Jan 31 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
Sep 07 Python
python如何实现单链表的反转
Feb 10 Python
python实现扑克牌交互式界面发牌程序
Apr 22 Python
Python如何实现定时器功能
May 28 Python
解决Keras TensorFlow 混编中 trainable=False设置无效问题
Jun 28 Python
如何基于Django实现上下文章跳转
Sep 16 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 select,radio和checkbox默认选择的实现方法
2010/05/15 PHP
有关PHP性能优化的介绍
2013/06/20 PHP
php强制用户转向www域名的方法
2015/06/19 PHP
PHP获取日期对应星期、一周日期、星期开始与结束日期的方法
2018/06/22 PHP
jquery对dom的操作常用方法整理
2013/06/25 Javascript
前台js对象在后台转化java对象的问题探讨
2013/12/20 Javascript
Javascript中对象继承的实现小例
2014/05/12 Javascript
JS实现跟随鼠标闪烁转动色块的方法
2015/02/26 Javascript
javascript实现校验文件上传控件实例
2015/04/20 Javascript
AngularJS深入探讨scope,继承结构,事件系统和生命周期
2016/11/02 Javascript
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
2016/11/22 Javascript
jQuery学习笔记之入门
2016/12/14 Javascript
输入框点击时边框变色效果的实现方法
2016/12/26 Javascript
ajax的分页查询示例(不刷新页面)
2017/01/11 Javascript
JS 在数组指定位置插入/删除数据的方法
2017/01/12 Javascript
Easyui使用Dialog行内按钮布局的实例
2017/07/27 Javascript
小程序清理本地缓存的方法
2018/08/17 Javascript
微信小程序实现多选框全选与取消全选功能示例
2019/05/14 Javascript
微信小程序云开发实现增删改查功能
2019/05/17 Javascript
vue 实现滚动到底部翻页效果(pc端)
2019/07/31 Javascript
js实现弹窗猜数字游戏
2020/11/26 Javascript
python字典get()方法用法分析
2015/04/17 Python
Python实现对PPT文件进行截图操作的方法
2015/04/28 Python
TensorFlow神经网络优化策略学习
2018/03/09 Python
对python打乱数据集中X,y标签对的方法详解
2018/12/14 Python
Python数组拼接np.concatenate实现过程
2020/04/18 Python
Django多层嵌套ManyToMany字段ORM操作详解
2020/05/19 Python
Python如何将将模块分割成多个文件
2020/08/04 Python
Python基于Serializer实现字段验证及序列化
2020/11/04 Python
详解如何在css中引入自定义字体(font-face)
2018/05/17 HTML / CSS
菲律宾领先的在线时尚商店:Zalora菲律宾
2018/02/08 全球购物
意大利买卖二手奢侈品网站:LAMPOO
2020/06/03 全球购物
城市轨道专业个人求职信范文
2013/09/23 职场文书
公务员党员评议表自我鉴定
2014/09/14 职场文书
SQL语句多表联合查询的方法示例
2022/04/18 MySQL
Python时间操作之pytz模块使用详解
2022/06/14 Python