小议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 07 Python
python3调用R的示例代码
Feb 23 Python
解决Python print 输出文本显示 gbk 编码错误问题
Jul 13 Python
pyqt5 tablewidget 利用线程动态刷新数据的方法
Jun 17 Python
python启动应用程序和终止应用程序的方法
Jun 28 Python
Python自动化测试笔试面试题精选
Mar 12 Python
Python3 利用face_recognition实现人脸识别的方法
Mar 13 Python
python将dict中的unicode打印成中文实例
May 11 Python
keras topN显示,自编写代码案例
Jul 03 Python
基于python实现操作git过程代码解析
Jul 27 Python
Python tkinter实现日期选择器
Feb 22 Python
Jupyter Notebook内使用argparse报错的解决方案
Jun 03 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
WINDOWS下php5.2.4+mysql6.0+apache2.2.4+ZendOptimizer-3.3.0配置
2008/03/28 PHP
mac环境中使用brew安装php5.5.15
2014/08/18 PHP
PHP如何使用Memcached
2016/04/05 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
使用Jquery Aajx访问WCF服务(GET、POST、PUT、DELETE)
2012/03/16 Javascript
js操作输入框提示信息且响应鼠标事件
2014/03/25 Javascript
jQuery中prevAll()方法用法实例
2015/01/08 Javascript
在JavaScript中访问字符串的子串
2015/07/07 Javascript
javascript数组去重的六种方法汇总
2015/08/16 Javascript
jQuery 1.9.1源码分析系列(十四)之常用jQuery工具
2015/12/02 Javascript
javascript时间排序算法实现活动秒杀倒计时效果
2021/01/28 Javascript
BootStrap的JS插件之轮播效果案例详解
2016/05/16 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
2016/07/11 Javascript
AngularJS实现根据变量改变动态加载模板的方法
2016/11/04 Javascript
jQuery Ajax实现跨域请求
2017/01/21 Javascript
js实现彩色条纹滚动条效果
2017/03/15 Javascript
Vue header组件开发详解
2018/01/26 Javascript
如何在vue中使用ts的示例代码
2018/02/28 Javascript
vue iView 上传组件之手动上传功能
2018/03/16 Javascript
Angular6封装http请求的步骤详解
2018/08/13 Javascript
React手稿之 React-Saga的详解
2018/11/12 Javascript
微信jssdk逻辑在vue中的运用详解
2018/11/14 Javascript
jQuery访问json文件中数据的方法示例
2019/01/28 jQuery
layui自定义工具栏的方法
2019/09/19 Javascript
bootstrap table实现iview固定列的效果实例代码详解
2019/09/30 Javascript
selenium 反爬虫之跳过淘宝滑块验证功能的实现代码
2020/08/27 Javascript
python模仿网页版微信发送消息功能
2018/02/24 Python
单利模式及python实现方式详解
2018/03/20 Python
利用Python代码实现数据可视化的5种方法详解
2018/03/25 Python
越南电子产品购物网站:FPT Shop
2017/12/02 全球购物
生产现场工艺工程师岗位职责
2013/11/28 职场文书
学生违反校规检讨书
2014/10/28 职场文书
前台文员岗位职责
2015/02/04 职场文书
应届毕业生的自我评价
2019/06/21 职场文书
企业开发CSS命名BEM代码规范实践
2022/02/12 HTML / CSS
Python中time与datetime模块使用方法详解
2022/03/31 Python