小议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实现html转ubb代码(html2ubb)
Jul 03 Python
python中readline判断文件读取结束的方法
Nov 08 Python
python内置数据类型之列表操作
Nov 12 Python
python实现事件驱动
Nov 21 Python
Scrapy框架爬取Boss直聘网Python职位信息的源码
Feb 22 Python
详解利用python+opencv识别图片中的圆形(霍夫变换)
Jul 01 Python
Python Multiprocessing多进程 使用tqdm显示进度条的实现
Aug 13 Python
Python目录和文件处理总结详解
Sep 02 Python
Flask 上传自定义头像的实例详解
Jan 09 Python
python deque模块简单使用代码实例
Mar 12 Python
Python 私有属性和私有方法应用场景分析
Jun 19 Python
使用anaconda安装pytorch的实现步骤
Sep 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
php获取网页内容方法总结
2008/12/04 PHP
php socket实现的聊天室代码分享
2014/08/16 PHP
PHP扩展mcrypt实现的AES加密功能示例
2019/01/29 PHP
javascript继承之为什么要继承
2012/11/10 Javascript
浅析JS刷新框架中的其他页面 && JS刷新窗口方法汇总
2013/07/08 Javascript
jquery 列表双向选择器之改进版
2013/08/09 Javascript
jquery validate添加自定义验证规则(验证邮箱 邮政编码)
2013/12/04 Javascript
javascript实现checkBox的全选,反选与赋值
2015/03/12 Javascript
jQuery实现限制textarea文本框输入字符数量的方法
2015/05/28 Javascript
javascript insertAfter()定义与用法示例
2016/07/25 Javascript
JS正则替换掉小括号及内容的方法
2016/11/29 Javascript
jquery实现左右滑动式轮播图
2017/03/02 Javascript
利用webstrom调试Vue.js单页面程序的方法教程
2017/06/06 Javascript
JS排序算法之希尔排序与快速排序实现方法
2017/12/12 Javascript
react build 后打包发布总结
2018/08/24 Javascript
vue侧边栏动态生成下级菜单的方法
2018/09/07 Javascript
Vue2.0实现组件之间数据交互和通信操作示例
2019/05/16 Javascript
vue下使用nginx刷新页面404的问题解决
2019/08/02 Javascript
微信小程序实现滑动翻页效果(完整代码)
2019/12/06 Javascript
使用jQuery实现购物车
2020/10/29 jQuery
JavaScript字符串转数字的简单实现方法
2020/11/27 Javascript
python发布模块的步骤分享
2014/02/21 Python
Python入门及进阶笔记 Python 内置函数小结
2014/08/09 Python
Python微信操控itchat的方法
2019/05/31 Python
Jupyter Notebook折叠输出的内容实例
2020/04/22 Python
Python csv文件记录流程代码解析
2020/07/16 Python
html5 横向滑动导航栏的方法示例
2020/05/08 HTML / CSS
来自全球大都市的高级街头服饰:Pegador
2018/01/03 全球购物
佳能加拿大网上商店:Canon eStore Canada
2018/04/04 全球购物
毕业自荐信
2013/12/16 职场文书
2014信息技术专业毕业生自我评价
2014/01/17 职场文书
警告通知
2015/04/25 职场文书
给领导敬酒词
2015/08/12 职场文书
《窃读记》教学反思
2016/02/18 职场文书
tomcat默认最大连接数及相关调整方法
2022/05/06 Servers
win10+RTX3050ti+TensorFlow+cudn+cudnn配置深度学习环境的方法
2022/06/25 Servers