当前位置:首页>python>《Python 从入门到精通》054|位置参数、默认参数、关键字参数,一篇讲透

《Python 从入门到精通》054|位置参数、默认参数、关键字参数,一篇讲透

  • 2026-09-02 16:06:41
《Python 从入门到精通》054|位置参数、默认参数、关键字参数,一篇讲透

上一章我们已经把函数最核心的骨架搭起来了。

你已经知道,函数不是一段被包起来的代码而已。 它是一个能接收输入、处理信息、再把结果交回来的小工具。

也正因为函数要接收输入,参数这件事就开始变得越来越重要。

前面我们只是先认识了参数,知道函数定义时可以在括号里留位置,调用时把具体值传进去。 但真正一写多了,你马上就会碰到几个非常现实的问题:

参数到底是按什么规则对应上的 有些参数每次都要传,有没有办法给个默认值 参数一多时,顺序总记不住怎么办 我能不能直接写参数名,把值指定给它 位置参数、默认参数、关键字参数,到底什么时候该用谁

这些问题如果没理顺,函数很容易写得又乱又脆。 但只要理顺了,你会明显感觉到:

函数不仅更灵活了,而且更顺手了。

这一章,我们就把参数里最基础、最常用、也最容易混的三件事讲透:

位置参数 默认参数 关键字参数

这三样看起来只是细节, 其实它们决定了你后面函数写得清不清楚、调得顺不顺手。

一、先把最基础的参数调用规则重新站稳

我们先从最普通的函数开始。

比如:

defshow_info(name, age):    print(f'我叫{name},今年{age}岁')

调用:

show_info('张三', 18)

输出:

我叫张三,今年18岁

这里其实已经隐含了一个很重要的规则:

第一个值 '张三' 对应第一个参数 name第二个值 18 对应第二个参数 age

这种靠顺序一一对应的方式,就是位置参数最核心的逻辑。

你现在先记一句特别重要的话:

只要你调用函数时,直接按顺序往里塞值,这些值通常就是按位置去匹配参数的。

这就是后面所有内容的起点。

二、什么是位置参数

位置参数,说白了就是:

按照位置顺序来传递的参数

比如:

defadd(a, b):return a + b

调用:

print(add(3, 5))

这里的 3 会给 a,5 会给 b。 为什么?

因为它们出现的位置就是这么排的。

第一个位置给第一个参数 第二个位置给第二个参数

再看一个稍微长一点的例子:

defstudent_info(name, age, city):    print(f'姓名:{name},年龄:{age},城市:{city}')

调用:

student_info('张三', 18, '北京')

输出:

姓名:张三,年龄:18,城市:北京

这里也是同样的道理。

张三 对应 name18 对应 age北京 对应 city

这就是最标准、最基础的位置参数调用方式。

三、位置参数为什么最容易上手

因为它最符合我们一开始的直觉。

函数定义里写了几个参数, 调用时就按顺序把几个值塞进去。

这种方式特别适合参数不多、含义也很清楚的函数。

比如:

defmultiply(a, b):return a * b

调用:

print(multiply(4, 6))

谁看到都不难理解。

再比如:

defget_total(price, count):return price * count

调用:

print(get_total(59.9, 3))

也很自然。

所以位置参数的优点就是:

简单 直接 适合短小函数 写起来快

这也是为什么你最先接触到的参数形式,几乎都是位置参数。

四、位置参数最容易犯的错,就是顺序错了

这点一定要单独拎出来说。

看函数:

defshow_info(name, age):    print(f'我叫{name},今年{age}岁')

正常调用:

show_info('张三', 18)

但如果你写成:

show_info(18, '张三')

程序大概率不会报错。 可输出会变成:

我叫18,今年张三岁

这就是位置参数的典型风险:

程序不一定提醒你 但结果可能已经悄悄错了

因为它根本不管你心里怎么想。 它只认位置。

第一个值就给第一个参数 第二个值就给第二个参数

所以位置参数虽然简单,但只要参数一多,或者含义稍微相近,就很容易传错顺序。

这也是为什么后面关键字参数会那么有用。

五、位置参数个数也必须对上

除了顺序,数量也得对。

比如:

defadd(a, b):return a + b

你正常应该传两个值。

print(add(3, 5))

如果你只传一个:

print(add(3))

就会报错。

如果你传三个:

print(add(3, 5, 7))

也会报错。

因为这个函数明确说了,它要两个参数。 那你就得不多不少,正好给两个。

所以位置参数最基础的两条规则就是:

顺序要对 个数要对

只要这两条出问题,函数调用就会不顺。

六、如果某个参数大多数时候都一样,怎么办

这时候默认参数就该出场了。

来看一个很典型的例子。

比如你想写一个函数,打印欢迎语。 大多数时候,欢迎对象的城市都写成 北京。 偶尔才会变。

如果还像普通位置参数那样写:

defwelcome(name, city):    print(f'欢迎{name},你来自{city}')

那每次调用都要写城市:

welcome('张三', '北京')welcome('李四', '北京')welcome('王五', '上海')

你会发现,北京 被重复传了好多次。 这就有点累。

这时候就可以给参数一个默认值:

defwelcome(name, city='北京'):    print(f'欢迎{name},你来自{city}')

这样调用时:

welcome('张三')welcome('李四')welcome('王五', '上海')

输出:

欢迎张三,你来自北京欢迎李四,你来自北京欢迎王五,你来自上海

这就是默认参数最直接的价值:

大多数时候一样的内容,不用每次都手动再传一遍。

七、什么是默认参数

默认参数,就是:

在定义函数时,先给某个参数一个默认值 如果调用时没传,就自动用这个值 如果传了,就用你传的那个

形式长这样:

def 函数名(参数=默认值):    ...

比如:

defsay_hello(name, word='你好'):    print(f'{word},{name}')

调用:

say_hello('张三')say_hello('李四', '欢迎')

输出:

你好,张三欢迎,李四

你会发现,默认参数本质上是在给函数准备一个 兜底值。

你不给,我就用默认的。 你给了,我就尊重你的输入。

这会让函数既有默认行为,又保留灵活性。

八、默认参数特别适合哪些场景

特别适合这类情况:

某个参数常常有固定值 但偶尔又允许修改

比如打印分隔线:

defprint_line(char='-', count=20):    print(char * count)

调用:

print_line()print_line('*', 10)

输出:

--------------------**********

你看,这就很顺。

平时不用多想,直接调用就有默认效果。 真要变,也可以临时改。

再比如发通知时,默认签名固定:

defsend_message(name, sender='系统管理员'):    print(f'{name},请查收。发送人:{sender}')

大多数时候你不用传 sender, 但偶尔你也可以指定。

这就是默认参数特别好用的地方。

九、默认参数和位置参数可以一起用

当然可以。

其实最常见的函数写法之一,就是:

前面放普通位置参数 后面放带默认值的参数

比如:

defstudent_info(name, age, city='北京'):    print(f'姓名:{name},年龄:{age},城市:{city}')

调用:

student_info('张三', 18)student_info('李四', 20, '上海')

输出:

姓名:张三,年龄:18,城市:北京姓名:李四,年龄:20,城市:上海

这里:

name 和 age 是必须传的city 是可选的,不传就默认北京

这就是很典型的函数设计思路:

核心参数必须给 附加参数可以有默认值

你以后写函数时,这种结构会特别常见。

十、为什么默认参数要放在后面

这个规则很重要。

比如下面这种写法就是不合适的:

defshow_info(city='北京', name, age):    ...

为什么不行?

因为调用时程序会很难判断:

你传进来的第一个值,到底该对应哪个参数

而如果写成这样:

defshow_info(name, age, city='北京'):    ...

就很清楚了。

必须传的先匹配 可选的放后面补充

所以你先记住一个非常实用的规则:

默认参数通常放在普通位置参数后面

这不仅是语法习惯,也符合人的阅读和调用直觉。

十一、默认参数不是让你少写代码而已,它还在表达“推荐配置”

这个角度特别值得理解。

比如:

defconnect_db(host='127.0.0.1', port=3306):    print(f'连接数据库:{host}:{port}')

这里的默认值不只是为了偷懒。 它其实还在表达一层意思:

通常情况下,我建议就用这个配置

再比如:

defformat_score(score, digits=1):returnf'{score:.{digits}f}'

这里 digits 如果以后设计得更完整,默认值也可以表达:

平时我们建议保留 1 位小数

所以默认参数除了方便调用, 还在向使用者传达:

这个函数平时推荐怎么用

这也是为什么函数写得好不好,和参数设计关系非常大。

十二、接下来是关键字参数:参数一多时,终于不用死记顺序了

我们先看一个例子。

函数:

defstudent_info(name, age, city):    print(f'姓名:{name},年龄:{age},城市:{city}')

如果用位置参数调用:

student_info('张三', 18, '北京')

当然可以。

但你有没有发现,参数一多时,眼睛其实挺累。

尤其是以后函数再复杂一点,比如:

defcreate_user(name, age, city, email, phone):    ...

这时候你再纯靠位置传值,很容易写错、看错、改错。

这时候,关键字参数就特别香了。

调用可以写成:

student_info(name='张三', age=18, city='北京')

这里就是关键字参数。

十三、什么是关键字参数

关键字参数,就是:

调用函数时,明确写出 参数名=值

比如:

defshow_info(name, age):    print(f'我叫{name},今年{age}岁')

你可以这样调用:

show_info(name='张三', age=18)

也可以这样:

show_info(age=18, name='张三')

输出都是:

我叫张三,今年18岁

你会发现,关键字参数最大的好处就是:

顺序不再那么重要了

因为你已经明确告诉函数:

这个值给谁 那个值给谁

这会让代码清晰很多。

十四、关键字参数为什么特别适合参数多的函数

因为它让函数调用变得像填表。

比如:

defcreate_user(name, age, city, email):    print(name, age, city, email)

如果只写位置参数:

create_user('张三', 18, '北京', 'test@example.com')

虽然能跑,但你得花点时间确认:

第三个到底是城市还是邮箱 第四个到底是邮箱还是手机号

可如果写成关键字参数:

create_user(name='张三', age=18, city='北京', email='test@example.com')

就一眼看明白了。

这就是关键字参数最核心的优势:

可读性特别强

尤其是当参数有四五个以上时,这个优势会越来越明显。

十五、关键字参数还能避免位置传错的问题

比如:

defrectangle(length, width):    print(length * width)

用位置参数时,你要记得哪个在前,哪个在后。

但如果写成关键字参数:

rectangle(length=5, width=3)

就非常清楚。

再比如:

defuser_info(name, age, city):    print(f'{name}-{age}-{city}')

你如果位置写错,程序不一定报错。 但关键字参数就不容易出现这种 silent bug。

因为你已经明确地说了:

这个值就是给 name这个值就是给 age

所以关键字参数不仅让调用更清楚, 也在帮你减少低级错误。

十六、位置参数和关键字参数,可以混着用吗

可以,但有规则。

比如:

defshow_info(name, age, city):    print(f'姓名:{name},年龄:{age},城市:{city}')

你可以这样写:

show_info('张三', age=18, city='北京')

这没问题。

但你不能这样写:

show_info(name='张三', 18, city='北京')

这就不合适了。

为什么?

因为一旦开始用关键字参数,再在后面塞纯位置参数,调用顺序就会很混乱。

所以你先记住一个简单规则:

可以先写位置参数,再写关键字参数 但不要先写关键字参数,再写位置参数

这条规则非常实用。

十七、三种参数放在一起看,你就更容易理解

我们来看一个统一例子:

defgreet(name, word='你好'):    print(f'{word},{name}')

调用方式一,纯位置参数:

greet('张三')greet('李四', '欢迎')

调用方式二,关键字参数:

greet(name='王五')greet(name='赵六', word='早上好')

调用方式三,混合:

greet('小明', word='晚上好')

你会发现:

位置参数负责按顺序快速传值 默认参数负责提供默认行为 关键字参数负责让调用更清楚、更灵活

这三者不是互相替代的关系。 而是你写函数时可以组合使用的三种基础手段。

十八、一个特别常见的实战函数:商品总价计算

比如:

defget_total(price, count=1, discount=1):return price * count * discount

这里:

price 是必须传的count 默认 1discount 默认 1

调用时你可以很灵活:

print(get_total(100))print(get_total(100, 3))print(get_total(100, 3, 0.8))print(get_total(100, discount=0.8))

输出大概是:

100300240.080.0

这个函数特别有代表性。

因为现实里很多函数,恰恰就是这样设计的:

必须给核心输入 其他参数可以用默认值兜底 当调用者有特殊需求时,再通过关键字参数定制

这就是参数设计真正开始有味道的地方。

十九、再看一个很像文本处理工具的例子

比如写一个函数,把文本整理成统一格式。

defclean_text(text, to_lower=True):    text = text.strip()if to_lower:        text = text.lower()return text

调用:

print(clean_text('  PYTHON  '))print(clean_text('  PYTHON  ', to_lower=False))

输出:

pythonPYTHON

这里的 to_lower=True 就很典型。

大多数时候,我们希望统一转小写。 所以默认值是 True。 但偶尔如果不想转,也可以通过关键字参数改掉。

这比你写两个类似函数会自然得多。

二十、什么时候优先用位置参数

一般来说,当函数参数不多,而且含义非常明确时,位置参数最省事。

比如:

defadd(a, b):return a + b

调用:

add(3, 5)

就很好。

再比如:

defarea(length, width):return length * width

调用:

area(5, 3)

也很自然。

所以位置参数适合的通常是:

参数少 顺序清晰 一眼就不容易搞错

这种时候,没必要强行全写关键字参数。

二十一、什么时候优先考虑默认参数

当某个参数大多数时候都一样, 但又希望保留调整空间时,默认参数特别合适。

比如:

defprint_line(char='-', count=20):    print(char * count)

你平时直接调用就行。 需要特殊样式时,再改参数。

所以默认参数特别适合:

常用值比较固定 偶尔需要改 不想每次都重复传同样内容

它不是为了炫技巧, 而是在给函数建立一个更舒服的默认行为。

二十二、什么时候关键字参数特别值得用

当参数比较多、意义容易混、调用时希望更清楚时,关键字参数很值得用。

比如:

defcreate_user(name, age, city, email):    ...

这种函数如果全靠位置传值, 调用时很容易眼花。

而写成:

create_user(name='张三', age=18, city='北京', email='test@example.com')

就特别清楚。

所以关键字参数特别适合:

参数多 顺序不好记 希望调用代码更自解释 希望少犯位置传错的错误

这一点在真实项目里非常常见。

二十三、最容易犯的几个错

第一,位置参数顺序传错。 程序未必报错,但结果可能悄悄错掉。

第二,默认参数放在普通参数前面。 这通常不合适,也容易引发语法问题。

第三,函数定义有默认参数,调用时却忘了自己可以省略它,于是每次还在机械重复传一样的值。

第四,关键字参数和位置参数混用时顺序写反。 一定记得:先位置,后关键字。

第五,函数一复杂就全靠位置参数硬传,导致调用处可读性越来越差。 这时候往往该考虑关键字参数了。

二十四、这一章最该建立的,不是术语,而是参数设计意识

很多人学到这里,容易把注意力全放在名字上:

这叫位置参数 那叫默认参数 那又叫关键字参数

这些名字当然要知道。 但更重要的是,你要慢慢建立一个感觉:

我的函数到底需要几个必要输入 哪些是必须给的 哪些可以给默认值 哪些在调用时容易写混,应该考虑关键字参数

这其实已经不是简单记忆了, 而是在开始学怎么设计一个更好用的函数。

这一步非常关键。 因为后面函数一多,程序顺不顺,往往就取决于参数设计得好不好。

二十五、练习题:这一章一定要手敲

下面这些小练习特别有代表性,建议你自己敲一遍。

1. 定义一个函数,接收姓名和年龄,打印个人信息

defshow_info(name, age):    print(f'我叫{name},今年{age}岁')show_info('张三', 18)

2. 定义一个函数,接收价格和数量,数量默认是 1

defget_total(price, count=1):return price * countprint(get_total(100))print(get_total(100, 3))

3. 用关键字参数调用上面的函数

print(get_total(price=100, count=3))print(get_total(price=100))

4. 定义一个函数,打印欢迎语,默认问候词是 你好

defgreet(name, word='你好'):    print(f'{word},{name}')greet('李四')greet('王五', '欢迎')greet(name='赵六', word='早上好')

5. 定义一个函数,接收长和宽,返回面积,并分别用位置参数和关键字参数调用

defarea(length, width):return length * widthprint(area(5, 3))print(area(length=5, width=3))

你把这几题敲顺,位置参数、默认参数、关键字参数的感觉就会稳定很多。

二十六、本章小结

这一章你真正要带走的,不只是三个名字,而是一套更细的参数使用思路。

位置参数,按顺序传值,简单直接。 默认参数,给函数准备好常用默认行为。 关键字参数,让调用更清楚,也更不容易传错。

你要记住几件最实用的事:

位置参数看顺序 默认参数看兜底 关键字参数看清晰度 默认参数通常放在普通参数后面 混用时一般先位置,再关键字

从这一章开始,函数不只是能接收参数了, 而是开始学会用更合理的方式接收参数。

这一步特别关键。 因为它会直接影响你后面函数写得灵不灵活、顺不顺手、清不清楚。

下一章我们继续讲 可变参数 *args 和 **kwargs 到底怎么理解。 到那一章,你会发现,前面这些参数虽然已经够常用了,但还有一种场景很现实:

你压根不确定以后会传几个参数。

最新文章

随机文章