Python如何定义有默认参数的函数


Posted in Python onAugust 10, 2020

问题

你想定义一个函数或者方法,它的一个或多个参数是可选的并且有一个默认值。

解决方案

定义一个有可选参数的函数是非常简单的,直接在函数定义中给参数指定一个默认值,并放到参数列表最后就行了。例如:

def spam(a, b=42):
  print(a, b)

spam(1) # Ok. a=1, b=42
spam(1, 2) # Ok. a=1, b=2

如果默认参数是一个可修改的容器比如一个列表、集合或者字典,可以使用None作为默认值,就像下面这样:

# Using a list as a default value
def spam(a, b=None):
  if b is None:
    b = []
  ...

如果你并不想提供一个默认值,而是想仅仅测试下某个默认参数是不是有传递进来,可以像下面这样写:

_no_value = object()

def spam(a, b=_no_value):
  if b is _no_value:
    print('No b value supplied')
  ...

我们测试下这个函数:

>>> spam(1)
No b value supplied
>>> spam(1, 2) # b = 2
>>> spam(1, None) # b = None
>>>

仔细观察可以发现到传递一个None值和不传值两种情况是有差别的。

讨论

定义带默认值参数的函数是很简单的,但绝不仅仅只是这个,还有一些东西在这里也深入讨论下。

首先,默认参数的值仅仅在函数定义的时候赋值一次。试着运行下面这个例子:

>>> x = 42
>>> def spam(a, b=x):
...   print(a, b)
...
>>> spam(1)
1 42
>>> x = 23 # Has no effect
>>> spam(1)
1 42
>>>

注意到当我们改变x的值的时候对默认参数值并没有影响,这是因为在函数定义的时候就已经确定了它的默认值了。

其次,默认参数的值应该是不可变的对象,比如None、True、False、数字或字符串。 特别的,千万不要像下面这样写代码:

def spam(a, b=[]): # NO!
  ...

如果你这么做了,当默认值在其他地方被修改后你将会遇到各种麻烦。这些修改会影响到下次调用这个函数时的默认值。比如:

>>> def spam(a, b=[]):
...   print(b)
...   return b
...
>>> x = spam(1)
>>> x
[]
>>> x.append(99)
>>> x.append('Yow!')
>>> x
[99, 'Yow!']
>>> spam(1) # Modified list gets returned!
[99, 'Yow!']
>>>

这种结果应该不是你想要的。为了避免这种情况的发生,最好是将默认值设为None, 然后在函数里面检查它,前面的例子就是这样做的。

在测试None值时使用 is 操作符是很重要的,也是这种方案的关键点。 有时候大家会犯下下面这样的错误:

def spam(a, b=None):
  if not b: # NO! Use 'b is None' instead
    b = []
  ...

这么写的问题在于尽管None值确实是被当成False, 但是还有其他的对象(比如长度为0的字符串、列表、元组、字典等)都会被当做False。 因此,上面的代码会误将一些其他输入也当成是没有输入。比如:

>>> spam(1) # OK
>>> x = []
>>> spam(1, x) # Silent error. x value overwritten by default
>>> spam(1, 0) # Silent error. 0 ignored
>>> spam(1, '') # Silent error. '' ignored
>>>

最后一个问题比较微妙,那就是一个函数需要测试某个可选参数是否被使用者传递进来。 这时候需要小心的是你不能用某个默认值比如None、 0或者False值来测试用户提供的值(因为这些值都是合法的值,是可能被用户传递进来的)。 因此,你需要其他的解决方案了。

为了解决这个问题,你可以创建一个独一无二的私有对象实例,就像上面的_no_value变量那样。 在函数里面,你可以通过检查被传递参数值跟这个实例是否一样来判断。 这里的思路是用户不可能去传递这个_no_value实例作为输入。 因此,这里通过检查这个值就能确定某个参数是否被传递进来了。

这里对 object() 的使用看上去有点不太常见。object 是python中所有类的基类。 你可以创建 object 类的实例,但是这些实例没什么实际用处,因为它并没有任何有用的方法, 也没有任何实例数据(因为它没有任何的实例字典,你甚至都不能设置任何属性值)。 你唯一能做的就是测试同一性。这个刚好符合我的要求,因为我在函数中就只是需要一个同一性的测试而已。

以上就是Python如何定义有默认参数的函数的详细内容,更多关于Python定义有默认参数的函数的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python入门_浅谈逻辑判断与运算符
May 16 Python
Python输出由1,2,3,4组成的互不相同且无重复的三位数
Feb 01 Python
解决pyinstaller打包exe文件出现命令窗口一闪而过的问题
Oct 31 Python
Python3.5常见内置方法参数用法实例详解
Apr 29 Python
Python pygame绘制文字制作滚动文字过程解析
Dec 12 Python
Python concurrent.futures模块使用实例
Dec 24 Python
flask框架自定义url转换器操作详解
Jan 25 Python
解决python3插入mysql时内容带有引号的问题
Mar 02 Python
Python socket处理client连接过程解析
Mar 18 Python
python实现四人制扑克牌游戏
Apr 22 Python
Python 操作SQLite数据库的示例
Oct 16 Python
python 如何在list中找Topk的数值和索引
May 20 Python
如何更换python默认编辑器的背景色
Aug 10 #Python
django前端页面下拉选择框默认值设置方式
Aug 09 #Python
解决Django响应JsonResponse返回json格式数据报错问题
Aug 09 #Python
django 获取字段最大值,最新的记录操作
Aug 09 #Python
在django中查询获取数据,get, filter,all(),values()操作
Aug 09 #Python
Python 使用双重循环打印图形菱形操作
Aug 09 #Python
Python 添加文件注释和函数注释操作
Aug 09 #Python
You might like
PHP 删除文件与文件夹操作 unlink()与rmdir()这两个函数的使用
2011/07/17 PHP
php魔术方法功能与用法实例分析
2016/10/19 PHP
PHP使用Redis长连接的方法详解
2018/02/12 PHP
jquery清空textarea等输入框实现代码
2013/04/22 Javascript
JS实现自动切换文字的导航效果代码
2015/08/27 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
2015/09/02 Javascript
第四章之BootStrap表单与图片
2016/04/25 Javascript
JS实现控制文本框的内容
2016/07/10 Javascript
解决nodejs中使用http请求返回值为html时乱码的问题
2017/02/18 NodeJs
web前端vue之vuex单独一文件使用方式实例详解
2018/01/11 Javascript
Angular进行简单单元测试的实现方法实例
2020/08/16 Javascript
[01:32]DOTA2 2015国际邀请赛中国区预选赛第四日战报
2015/05/29 DOTA
Python中用pycurl监控http响应时间脚本分享
2015/02/02 Python
python按照多个字符对字符串进行分割的方法
2015/03/17 Python
linux下python使用sendmail发送邮件
2018/05/22 Python
mac 安装python网络请求包requests方法
2018/06/13 Python
python进行两个表格对比的方法
2018/06/27 Python
解决python中用matplotlib画多幅图时出现图形部分重叠的问题
2019/07/07 Python
浅析Windows 嵌入python解释器的过程
2019/07/26 Python
Python中的相关分析correlation analysis的实现
2019/08/29 Python
基于python全局设置id 自动化测试元素定位过程解析
2019/09/04 Python
python 检查数据中是否有缺失值,删除缺失值的方式
2019/12/02 Python
python批量替换文件名中的共同字符实例
2020/03/05 Python
纯css3无js实现的Android Logo(有简单动画)
2013/01/21 HTML / CSS
纯CSS3实现自定义Tooltip边框涂鸦风格的教程
2014/11/05 HTML / CSS
基于 HTML5 WebGL 实现的医疗物流系统
2019/10/08 HTML / CSS
Missguided美国官网:英国时尚品牌
2018/01/18 全球购物
意大利在线药房:Farmacia Loreto Gallo
2019/08/09 全球购物
Urban Decay官方网站:美国化妆品品牌
2020/06/04 全球购物
应届医学毕业生求职信分享
2013/12/02 职场文书
优秀民警事迹材料
2014/01/29 职场文书
《梅花魂》教学反思
2014/04/30 职场文书
运动会入场口号
2014/06/07 职场文书
群众路线教育实践活动总结
2014/10/30 职场文书
大学生实习推荐信
2015/03/27 职场文书
小学教师个人工作总结2015
2015/04/20 职场文书