当前位置:首页>python>自学编程第16课:Python函数的偷懒技巧——默认参数、关键字参数、可变参数

自学编程第16课:Python函数的偷懒技巧——默认参数、关键字参数、可变参数

  • 2026-10-11 07:51:30
自学编程第16课:Python函数的偷懒技巧——默认参数、关键字参数、可变参数

昨天Tyree写完第15课的作业,得意得很。他把猜数字游戏用函数改得整整齐齐,还跑来给我演示:“妈妈你看,我现在想加一个新功能,只需要改一个函数就行,不用到处翻代码了。”

我说:“那你知道函数还能更灵活吗?比如你写一个打招呼的函数,有时候想叫‘朋友’,有时候想叫‘同学’,有时候想叫全名,怎么办?”

他说:“那就多写几个函数呗,

greet_friend()、greet_classmate()……”

我打断他:“其实不用那么麻烦。你可以给参数设默认值,不传的时候它自动用默认的,传了就用你传的。”

他试了试,觉得挺好。然后他又问:“那如果我写一个求和函数,有时候传2个数,有时候传100个数,参数个数不确定怎么办?”

我说:“那就用*args,它能把所有传进来的数打包成一个元组,你想加几个加几个。”

他很高兴:“这个好!那我就可以写一个万能计算器了。”

今天我们就来学这些让函数“更聪明”的写法:默认参数、关键字参数、可变参数*args和**kwargs。

学会了你的函数就能适应各种奇怪的需求,想怎么调就怎么调。

01. 

默认参数:给参数一个“保底值”

我们先写一个最简单的打招呼函数:

这个函数要求必须传一个name进去。如果你忘了传,比如写greet(),Python就会翻脸,报错说缺少一个参数。

但有时候我们想让这个函数“聪明”一点:如果传了名字,就用传的名字;如果没传,就默认叫“朋友”。

这就用到了默认参数。写法很简单,在定义参数的时候用等号给它一个默认值:

greet()           # 不传参数,输出:你好,朋友

greet("Tyree")    # 传参数,输出:你好,Tyree

注意,name="朋友"这里的等号不是赋值,而是在告诉Python:“如果你没收到这个参数,就用‘朋友’顶上。”这是一个保底值。

有一个很容易踩的坑:带默认值的参数必须放在后面。比如def func(a, b=10):是正确的,但def func(a=10, b):就会报错。

为什么呢?因为Python匹配参数是按顺序来的,如果把默认参数放在前面,后面的普通参数就永远收不到值了。

Tyree刚开始就写反了,报错后他记住了:“默认参数往后站。”

02. 

关键字参数:调用时指名道姓

正常情况下,我们调用函数是按位置传参的:

info("Tyree", 12, "茂名")   # 按顺序:name, age, city

这种方式叫“位置参数”。顺序必须跟函数定义一致,一旦写错了,比如写成

info(12, "Tyree", "茂名"),程序不会报错,但会把12当成名字,“Tyree”当成年龄,逻辑全乱。

Python提供了一种更安全的方式:关键字参数。调用的时候直接写上参数名,顺序可以随便调换:

info(city="茂名", name="Tyree", age=12)   # 顺序乱写也没事

这样写,每个值都明确告诉Python要传给哪个参数,既不用记顺序,代码读起来也清楚。

Tyree后来写了一个注册函数,有七八个参数,他全部用关键字参数调用,说:“这样我自己不会搞混,别人看我的代码也一眼就懂。”

有一个小规则:关键字参数必须放在位置参数的后面。

比如info("Tyree", city="茂名", age=12)是可以的,但info(name="Tyree", 12, "茂名")就会报错。

03. 

可变参数 *args:接受任意多个位置参数

假如你想写一个求和函数,但用户可能传2个数,也可能传10个数——参数个数不确定,怎么办?难道要写10个版本吗?

不用。Python有一个写法叫*args,它会把所有多余的位置参数打包成一个元组(你可以把它当成一个列表来用):

这里的星号是关键。

它告诉Python:“把调用时传进来的所有位置参数,不管有多少个,统统收集起来,放进一个叫args的元组里。”

名字args可以随便取,但星号必须写。

Tyree第一次看到这个写法,问我:“为什么前面要加个星号?”

我让他试一下,如果写成

def sum_all(args):,调用sum_all(1,2,3)只会把(1,2,3)这个元组整体当成一个参数,函数体里循环一次就把整个元组当作一个数来处理,不会分别加。

他试了之后说:“哦,星号的意思是‘拆开装’。”没错,星号相当于一个收集袋,把散装的东西装到一起。

需要注意的是,*args只能接收不带名字的参数。

如果你写sum_all(a=1, b=2),它会报错,因为带名字的(关键字参数)不会被*args收走。

04. 

可变参数 **kwargs:接受任意多个关键字参数

*args处理的是没有名字的参数。那如果用户传进来的是name="Tyree"这种带名字的呢?用**kwargs。

两个星号的作用是:把所有传入的关键字参数打包成一个字典。字典的key是参数名,value是参数值。你可以用.items()遍历它们。

items() 是字典自带的一个方法,它的作用是:把字典里的每一对“键-值”打包成一个元组,然后返回一个可以循环的视图。

Tyere问我:“为什么一个星号和两个星号不一样?”

我打了个比方:一个星号是把东西“排成一排”放进元组(像排队),两个星号是“贴上标签”放进字典(像快递柜,有取件码)。他听完后说:“我记住了,星号越多,结构越复杂。”

**kwargs必须放在所有参数的最后面。

05. 

综合使用:普通参数 + 默认参数 + *args + **kwargs

这些参数可以一起用,但顺序是固定的:

普通参数 → 默认参数 → *args → **kwargs。这个顺序不能乱,否则Python不知道哪个参数该归谁。

看下图代码

输出:

a= 1

b= 2

args= (3, 4, 5)

kwargs= {'name': 'Tyree', 'age': 12}

我们一步步看Python是怎么分配这些参数的:

第一个位置参数1,给了a。

第二个位置参数2,给了b(覆盖了默认值10)。

剩下的位置参数3,4,5,没有对应的普通参数了,所以被*args收走,变成元组(3,4,5)。

剩下的关键字参数

name="Tyree", age=12,没有对应的普通参数,被**kwargs收走,变成字典。

Tyree看了这个输出后说:“原来参数是这样一层层‘分配’的,先满足普通参数,再喂给*args,最后喂给**kwargs。”

他试着把b的默认值去掉,然后只传一个参数,结果报错了——因为b没有收到值。他总结:“顺序和数量都不能乱。”

06. 

小项目:用可变参数写一个“成绩计算器”

下面我们来写一个函数,接收任意多个成绩,返回总分、平均分、最高分、最低分。

代码看下图示:

这里有一个容易被忽略的地方:如果调用时一个成绩都没传

(比如analyze_scores()),scores就是一个空元组。这时候直接计算total / len(scores)就会触发ZeroDivisionError(除以零错误)。

所以函数开头要先判断一下:

if not scores:,意思是“如果scores是空的”,就直接返回四个0。

Tyree一开始没加这个判断,程序崩溃了,他说:“原来函数也要考虑‘没数据’的情况。”这就是所谓的“边界条件”——程序在正常情况和极端情况下都要能跑。

另外,return后面跟了四个值,Python会自动把它们打包成一个元组。

调用方可以像第一段代码那样用一个变量接住整个元组,然后通过索引([0]、[1])取出来;也可以像第二段代码那样用多个变量直接解包。Tyree更喜欢解包的方式,觉得更直观。

08.

今天学到了什么?


默认参数def func(a=默认值):,调用时可以不传,用默认值顶替。


关键字参数func(参数名=值),传参时指名道姓,顺序随便。

可变位置参数def func(*args):,收集所有多余的位置参数,打包成元组


可变关键字参数def func(**kwargs):,收集所有多余的关键字参数,打包成字典。


参数顺序:普通 → 默认 → *args → **kwargs 顺序乱了Python就不认得路了。

kwargs全称是 Keyword Arguments(关键字参数)。

kw = Keyword(关键字,就是参数名)

args = Arguments(参数)


合起来 kwargs 就是“关键字参数们”。这个命名习惯来自Python社区,就像 *args 代表“位置参数们”一样。

好了今天课程就到这里,明天第17课:变量的作用域(局部与全局)。我们会学为什么函数内部的变量改不了外面的,以及怎么用global声明。


Tyree已经碰到过这个问题了——他试过在函数里直接修改外面的变量,结果没成功,明天正好给他讲清楚。

————热门推荐————

自学编程第15课:函数——把代码打包成“小工具”(def、参数、返回值)可反复调用

自学编程第13课:字符串——让电脑帮你“玩文字”

自学编程第7课:turtle画图入门(画一个正方形,五角形,螺旋形,三角形)

自学编程第6课:列表+循环+判断(做一个学生成绩分析器)

自学编程第3课:变量与数学计算(做一个年龄计算器)

自学编程第2课:用input让电脑问你名字(做一个打招呼程序)

自学编程第一步:安装Python和Thonny(零基础图文教程)

(本系列教程每天更新,欢迎关注收藏)

最新文章

随机文章