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_arg1position_arg2仅仅只是位置参数

  • position_or_keyword可以是位置参数也可以是关键字参数

  • kwd1kwd2仅仅只是关键字参数

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 函数定义详解相关推荐

  1. 站长在线Python教程:Python中类定义详解

    导读:欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中类定义详解>. 我们在上一节内容<Python中面向对象相关概述详解>中学习过,类是具有相同 ...

  2. Python的零基础超详细讲解(第十二天)-Python函数及使用

    基础篇往期文章: Python的零基础超详细讲解(第一天)-Python简介以及下载_编程简单学的博客-CSDN博客 Python的零基础超详细讲解(第二天)-Python的基础语法1_编程简单学的博 ...

  3. 超详细分解c 语言——实现扫雷游戏(详解)

    之前利用三子棋程序,介绍探讨了 c语言简单游戏编写主要模块及使用方法. 今天,我们就利用这个经典扫雷游戏,来加强对于程序思路的编写及思路. 目录 前引 游戏规则介绍 一.基本游戏思路(游戏实现方法) ...

  4. python函数用法详解2(变量的作用域(全局变量、局部变量)、共享全局变量、函数返回值、函数的参数(位置参数、关键字参数、默认参数、不定长参数)、拆包、交换变量值、引用、可变和不可变类型)

    1. 变量作⽤域         变量作⽤域指的是变量⽣效的范围,主要分为两类:局部变量和全局变量. 局部变量         定义在函数体内部的变量,即只在函数体内部⽣效. def testA(): ...

  5. python函数练习题详解_Python练习题详解之函数3(小白友好)

    Python练习题详解之函数3(小白友好) 你好!欢迎来到Python练习题详解系列.为了让小白(也就是我本人)更好的理解代码,打好编程基础,我决定仔细地解说一些练习题.欢迎阅读!奥利给! 题目1 编 ...

  6. 七、C语言函数定义详解

    文章目录 1.函数的声明和定义 2.函数的调用 3.函数参数的两种传递方式 1.传值调用(C语言默认传递参数方式) 2.引用调用 4.函数的分类 1.内部函数(静态函数) 2.外部函数 1.函数的声明 ...

  7. matlab函数定义详解

    但凡经过编程熏陶的人,在学习其他一门陌生的编程语言时,往往会与已经学过的语言相比较.而语法的比较往往是情不自禁的.在matlab中,函数的概念或许没有其他语言那么广泛,特性没有那么丰富,但基本的功能都 ...

  8. 计算机科学类专升本复习之“C语言函数定义”详解(初稿)

    今天首先要讲的是C语言的无参函数定义 函数 如果不接收"用户传递"的数据,那么定义时可以不带参数 例如: dataType kangkang(){ //nb } dataType: ...

  9. 定义一个没有参数的函数、输出python3次_Python函数参数详解,三天让你掌握python,不再是小白

    原标题:Python函数参数详解,三天让你掌握python,不再是小白 引言 随着程序功能的增多,代码量随之增大,此时仍不加区分地把所有功能的实现代码放到一起,将会使得程序的组织结构不清晰,可读性变差 ...

最新文章

  1. js的eval函数解析后台返回的json数据时为什加上圆括号eval((+data+)),而HTML页面定义的数据不用...
  2. 某32岁大厂程序员吐槽:简历通过率才30%!大龄韭菜该何去何从?网友:没那么严重,同32岁,简历通过率90%!...
  3. Tree命令安装和使用
  4. ssm整合(基于xml配置方式)
  5. boost::core模块实现分配器分配提示
  6. Heap(堆结构/优先队列)-Swift实现
  7. dosubmit 成功不成功_供卵试管不成功的原因是什么?一般几次成功?
  8. vue.js 动态添加组件
  9. deactivate_sending在创建新的table entry时的作用
  10. Unity shader图集Atlas下的UV坐标归一化转换
  11. 【转】C#中StreamWriter与BinaryWriter的区别兼谈编码。
  12. JHipster简介
  13. python矩阵所有元素取整_Python主要逻辑基础与处理
  14. shell---字体颜色
  15. 神经网络算法开篇——逻辑回归
  16. 8种妙招,公众号实现吸粉引流
  17. uni-app关于tabBar配置
  18. 第二课 什么是norm game?(An Evolutionary Approach to Norms)
  19. 地图定位技术揭秘(三)
  20. 黑群号 阿里云 frp

热门文章

  1. 【最终解决】平板(手机)访问电脑文件(考研or办公)<kao一波三折>
  2. C#编程基础——综合项目实践:KTV点歌系统项目第三课:辅助类开发及登录窗体制作
  3. 我的狐仙老婆——游魂 -Kiss on my Deity-汉化第二版
  4. PairWork-电梯调度程序结对编程【附加题】
  5. php去除最后一个空格,php去除头尾空格的2种方法
  6. 潮水退后才知道谁在裸泳
  7. 搭建简单GAN生成MNIST手写体
  8. 如何制作一个产品画册二维码
  9. oracle 行转列和列转行的几种方式
  10. Java8 Lambda杀手锏