超详细!少数人才知道的 Python 函数定义详解
Python 函数定义时支持可变数量的参数。
一、默认值参数
在 Python 中给函数的参数指定默认值是一种十分常见的使用方式,这样在调用函数时,可以使用比定义时更少的参数。
示例代码
def chat_request(response, retries=4, reminder='Please try again!'):while True:response = input(response)if response in ('y', 'yes'):return Trueif response in ('n', 'no'):return Falseretries = retries - 1if retries < 0:raise ValueError('invalid user response')print(reminder)
示例代码中定义的函数chat_request
可以使用以下三种调用方式:
只给出必选实参response
chat_request('hello world!')
给出一个可选实参retries
chat_request('please say no or yes', 2)
给出所有实参response, retries, reminder
chat_request('please input your mind', 2, 'Dear Baby, but only yes or no!')
默认值在 定义
作用域里的函数定义中求值,为理解这句话的含义,请看如下示例。
Input:
name = 'tony'def get_name(arg=name):print(arg)name = 'lily'
get_name()
Output:
tony
PS: 默认值只计算一次,默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果。
例如,下面的get_num
函数会累积后续调用时传递的参数,可以发现输出结果与预期不一致。
Input:
def get_num(num, list1=[]):list1.append(num)return list1print(get_num(100))
print(get_num(200))
print(get_num(300))
Output:
[100]
[100, 200]
[100, 200, 300]
PS: 如果不想在后续调用之间共享默认值时,可采取以下方式改写get_num
函数
Input:
def get_num(num, list1=None):if list1 is None:list1 = []list1.append(num)return list1print(get_num(100))
print(get_num(200))
print(get_num(300))
Output:
[100]
[200]
[300]
二、关键字参数
在 Python 中也可以使用kwarg=value
形式的关键字参数来调用函数。
示例代码
def animal(name, state='active', action='fly', type='land'):print("This animal wouldn't", action, end=' ')print("if you reminder", name, "you are great.")print("-- general animal, the", type)print("-- They're", state, "!")
代码参数说明
animal
函数接受一个必选参数(name)和三个可选参数(state, action 和 type)。
该函数有以下几种调用方式。
animal('jingmao') # 1 positional argument
animal(name='keji') # 1 keyword argument
animal(name='chaiquan', action='running') # 2 keyword arguments
animal(action='sleep', name='pig') # 2 keyword arguments
animal('cat', 'smile', 'jump') # 3 positional arguments
animal('bird', state='inactive') # 1 positional, 1 keyword
以下都是无效的调用方式。
animal() # required argument missing
animal(name='rabbit', 'dead') # non-keyword argument after a keyword argument
animal('fox', name='bird') # duplicate value for the same argument
animal(profile='warning') # unknown keyword argument
函数调用时,关键字参数必须跟在位置参数后面。所有传递的关键字参数都必须匹配一个函数接受的参数。
例如,profile 不是函数 animal 的有效参数,关键字参数的顺序并不重要。这也包括必选参数
PS: 不能对同一个参数多次赋值。
下面的举例就是一个反例
def get_name(name):print(name)get_name('dog', name='cat')
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: get_name() got multiple values for argument 'name'
在 Python 中形参还可以是 **name
形式,指接收一个字典(kwarg=value),该字典包含与函数中已定义形参对应之外的所有关键字参数。
**name
形参可以与 *name
(指接收一个元组,该元组包含形参列表之外的位置参数)形参组合使用,请注意:*name 必须在 **name 前面
示例代码
Input:
def animalShop(animal_name, *arguments, **keywords):print("-- Do you have any", animal_name, "?")print("-- I'm sorry, we're all out of", animal_name)for argument in arguments:print(argument)print("*" * 40)for keyword in keywords:print(keyword, ":", keywords[keyword])
animalShop
函数可以使用如下方式调用
animalShop("dog", "It's very Cute, sir.","It's really very, VERY Smart, sir.",shopkeeper="tony",client="Online Shop",market="Chat Connect")
Output:
-- Do you have any dog ?
-- I'm sorry, we're all out of dog
It's very Cute, sir.
It's really very, VERY Smart, sir.
****************************************
shopkeeper : tony
client : Online Shop
market : Chat Connect
PS: 注意,关键字参数在输出结果中的顺序与调用函数时的顺序一致。
三、特殊参数
在 Python 函数中,默认情况下,参数可以按位置
或显式关键字
传递。
但为了让代码易读、高效,最好限制参数的传递方式,这样,开发者只需查看函数定义,即可确定参数项是仅按位置
、按位置或关键字
,还是仅按关键字
传递。
函数定义如下:
def function(position_arg1, position_arg2, /, position_or_keyword, *, kwd1, kwd2):pass
在function
函数定义中:
position_arg1
和position_arg2
仅仅只是位置参数position_or_keyword
可以是位置参数也可以是关键字参数kwd1
和kwd2
仅仅只是关键字参数
PS: /
和*
是可选的,这些符号表明形参如何把参数值传递给函数:位置、位置或关键字、关键字。关键字形参也叫作命名形参。
3.1 位置或关键字参数
函数定义中未使用 / 和 * 时,参数可以按位置或关键字传递给函数。
3.2 仅位置参数
细节补充一下,特定形参可以标记为 仅限位置
。
仅限位置
时,形参的顺序很重要,且这些形参不能用关键字传递。仅限位置形参应放在/
(正斜杠)前。/
用于在逻辑上分割仅限位置形参与其它形参。如果函数定义中没有/
,则表示没有仅限位置形参。/
后可以是 位置或关键字 或 仅限关键字 形参。
3.3 仅限关键字参数
细节补充一下,把形参标记为 仅限关键字
,表明必须以关键字参数形式传递该形参,应在参数列表中第一个 仅限关键字 形参前添加 *
。
示例代码
如下函数定义示例,注意 /
和 *
标记。
def standard_arg(arg):print(arg)def pos_only_arg(arg, /):print(arg)def kwd_only_arg(*, arg):print(arg)def union_example(pos_only, /, standard, *, kwd_only):print(pos_only, standard, kwd_only)
第一个函数定义 standard_arg 是最常见的形式,对调用方式没有任何限制,可以按位置也可以按关键字传递参数
# 按位置传递参数
standard_arg(200)
200
# 按关键字传递参数
standard_arg(arg=200)
200
第二个函数 pos_only_arg 的函数定义中有 /,仅限使用位置形参
# 按位置传递参数正常,无报错
pos_only_arg(100)
100# 按关键字传递参数异常,会抛异常
pos_only_arg(arg=100)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'
第三个函数 kwd_only_args 的函数定义通过 *
表明仅限关键字参数
# 按位置传递参数异常,会抛异常
kwd_only_arg(300)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given# 按关键字传递参数正常,无报错
kwd_only_arg(arg=300)
3
最后一个函数 union_example 在同一个函数定义中,使用了全部三种调用方式
# 第3个参数仅为关键字参数,这里使用位置参数传参,会报错
union_example(100, 200, 300)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: union_example() takes 2 positional arguments but 3 were given# 第2个参数使用位置参数传参,无报错
union_example(100, 200, kwd_only=300)
输出:100 200 300# 第2个参数使用关键字参数传参,无报错
union_example(100, standard=200, kwd_only=300)
输出:100 200 300# 第1个参数仅为位置参数,这里使用关键字参数传参,会报错
union_example(pos_only=100, standard=200, kwd_only=300)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: union_example() got some positional-only arguments passed as keyword arguments: 'pos_only'
位置参数与关键字参数key名称冲突
在 key_error 函数定义中,kwargs 把 name 当作键,可能与位置参数 name 产生潜在冲突
Input:
def key_error(name, **kwargs):return 'name' in kwargs
Output:
key_error('tony', **{'name': 'lucy'})
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: key_error() got multiple values for argument 'name'
冲突解决方法
在位置参数 name 后加上 / (仅限位置参数)就可以了。
此时,函数定义把 name 当作位置参数,'name' 也可以作为关键字参数的键了。
即:仅限位置形参的名称可以在 **kwargs 中使用,不会产生冲突。
def key_error(name, **kwargs):return 'name' in kwargskey_error('tony', **{'name': 'lucy'})
True
四、任意实参列表
在 Python 函数调用过程中使用任意数量的实参是不常见的,通常这些实参包含在元组中。
在可变数量的实参之前,可能有若干个普通参数,如下示例代码。
def person(p_file, separator, *args):p_file.write(separator.join(args))
*args
形参后的任何形式参数只能是仅限关键字参数,即只能用作关键字参数,不能用作位置参数,如下示例代码。
def test_concat(*args, sep="/"):return sep.join(args)test_concat("name", "sex", "age")
'name/sex/age'
test_concat("name", "sex", "age", sep=".")
'name.sex.age'
五、解包实参列表
在 Python 中函数调用需要独立的位置参数,如果是可变数量的位置参数,它的实参在列表或元组里时,要执行相反的操作。
例如,常用的内置 range()
函数要求传递独立的 start 和 stop 实参。
如果这些参数不是独立的,则要在调用函数时,用 *
操作符把实参从列表或元组解包出来。
示例代码
list(range(1, 4)) # normal call with separate arguments
输出:[1, 2, 3]moreNumber_args = [1, 4]
list(range(*moreNumber_args)) # call with arguments unpacked from a list
输出:[1, 2, 3]
同理,字典可以用 **
操作符传递关键字参数
def animal(name, state='active', action='fly'):print("This animal wouldn't", action, end=' ')print("if you reminder", name, "you are great.", end=' ')print("-- They're", state, "!")d = {"name": "dog", "state": "active", "action": "run"}animal(**d)
输出:This animal wouldn't run if you reminder dog you are great. -- They're active !
最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取【保证100%免费】
这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!
软件测试面试文档
我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
面试文档获取方式:
超详细!少数人才知道的 Python 函数定义详解相关推荐
- 站长在线Python教程:Python中类定义详解
导读:欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中类定义详解>. 我们在上一节内容<Python中面向对象相关概述详解>中学习过,类是具有相同 ...
- Python的零基础超详细讲解(第十二天)-Python函数及使用
基础篇往期文章: Python的零基础超详细讲解(第一天)-Python简介以及下载_编程简单学的博客-CSDN博客 Python的零基础超详细讲解(第二天)-Python的基础语法1_编程简单学的博 ...
- 超详细分解c 语言——实现扫雷游戏(详解)
之前利用三子棋程序,介绍探讨了 c语言简单游戏编写主要模块及使用方法. 今天,我们就利用这个经典扫雷游戏,来加强对于程序思路的编写及思路. 目录 前引 游戏规则介绍 一.基本游戏思路(游戏实现方法) ...
- python函数用法详解2(变量的作用域(全局变量、局部变量)、共享全局变量、函数返回值、函数的参数(位置参数、关键字参数、默认参数、不定长参数)、拆包、交换变量值、引用、可变和不可变类型)
1. 变量作⽤域 变量作⽤域指的是变量⽣效的范围,主要分为两类:局部变量和全局变量. 局部变量 定义在函数体内部的变量,即只在函数体内部⽣效. def testA(): ...
- python函数练习题详解_Python练习题详解之函数3(小白友好)
Python练习题详解之函数3(小白友好) 你好!欢迎来到Python练习题详解系列.为了让小白(也就是我本人)更好的理解代码,打好编程基础,我决定仔细地解说一些练习题.欢迎阅读!奥利给! 题目1 编 ...
- 七、C语言函数定义详解
文章目录 1.函数的声明和定义 2.函数的调用 3.函数参数的两种传递方式 1.传值调用(C语言默认传递参数方式) 2.引用调用 4.函数的分类 1.内部函数(静态函数) 2.外部函数 1.函数的声明 ...
- matlab函数定义详解
但凡经过编程熏陶的人,在学习其他一门陌生的编程语言时,往往会与已经学过的语言相比较.而语法的比较往往是情不自禁的.在matlab中,函数的概念或许没有其他语言那么广泛,特性没有那么丰富,但基本的功能都 ...
- 计算机科学类专升本复习之“C语言函数定义”详解(初稿)
今天首先要讲的是C语言的无参函数定义 函数 如果不接收"用户传递"的数据,那么定义时可以不带参数 例如: dataType kangkang(){ //nb } dataType: ...
- 定义一个没有参数的函数、输出python3次_Python函数参数详解,三天让你掌握python,不再是小白
原标题:Python函数参数详解,三天让你掌握python,不再是小白 引言 随着程序功能的增多,代码量随之增大,此时仍不加区分地把所有功能的实现代码放到一起,将会使得程序的组织结构不清晰,可读性变差 ...
最新文章
- js的eval函数解析后台返回的json数据时为什加上圆括号eval((+data+)),而HTML页面定义的数据不用...
- 某32岁大厂程序员吐槽:简历通过率才30%!大龄韭菜该何去何从?网友:没那么严重,同32岁,简历通过率90%!...
- Tree命令安装和使用
- ssm整合(基于xml配置方式)
- boost::core模块实现分配器分配提示
- Heap(堆结构/优先队列)-Swift实现
- dosubmit 成功不成功_供卵试管不成功的原因是什么?一般几次成功?
- vue.js 动态添加组件
- deactivate_sending在创建新的table entry时的作用
- Unity shader图集Atlas下的UV坐标归一化转换
- 【转】C#中StreamWriter与BinaryWriter的区别兼谈编码。
- JHipster简介
- python矩阵所有元素取整_Python主要逻辑基础与处理
- shell---字体颜色
- 神经网络算法开篇——逻辑回归
- 8种妙招,公众号实现吸粉引流
- uni-app关于tabBar配置
- 第二课 什么是norm game?(An Evolutionary Approach to Norms)
- 地图定位技术揭秘(三)
- 黑群号 阿里云 frp