Python 函数参数详解:位置、默认、可变与关键字参数

蓝鲸
蓝鲸
发布时间:2026-10-14| 5人浏览过
原创

本文深入解析 Python 函数参数的核心概念,涵盖位置参数、默认参数、可变参数(*args)及关键字参数(**kwargs)的定义与使用场景。重点讲解默认参数指向可变对象时的陷阱、命名关键字参数的作用及参数混合使用的严格顺序规则,帮助开发者编写更健壮、易读的 Python 代码。

Python 函数参数基础:形参与实参

形参与实参以及位置参数

什么是形参和实参

  • 形参,即形式参数,是指在函数定义阶段所指定的参数名称,用于接收调用时传入的值。例如在定义函数 max(a, b) 时,a 和 b 即为形参。
  • 实参,即实际参数,是指在调用函数时真正传递给函数的具体数值或对象。例如调用 max(1, 9) 时,1 和 9 即为实参。

位置参数与关键字传参

什么是位置参数

  • 在定义函数 max(a, b) 后,调用时无需指定参数名,只需按顺序传入值,如 max(1, 9)。此时实参根据位置与形参匹配,即 a 被赋值为 1,b 被赋值为 9。
  • 若不依赖位置顺序,可直接指定参数名进行调用,例如 max(b=9, a=1)。此时函数不再按入参顺序赋值,而是根据指定的参数名直接对应赋值。

默认参数的定义与陷阱

默认参数

编写一个计算 x 的 n 次幂的函数,要求 x 和 n 均可作为参数传入。


def power(x, n):
 return x ** n

print(power(2,2))

上述函数虽能解决问题,但存在冗余。若大部分调用仅需计算 x 的 2 次幂,每次调用仍需传入 n 显得多余。是否有方法减少调用时的入参数量?

若直接调用 print(power(2)),程序会报错,因为缺少必需的 n 参数。

在函数定义时,可通过等号赋值来设定默认参数。


def power(x, n=2):
 return x ** n

print(power(2))

注意:必选参数必须位于默认参数之前,否则会导致语法错误。

如果有多个默认参数呢?


def test(a=1, b=2, c=3):
 print("a=%d b=%d c=%d" % (a, b, c))

test(c=2)

当存在多个默认参数时,调用函数时可显式指定特定参数的值,使用参数名=参数值的形式即可。

如果默认参数是一个列表呢?


def test(L=[]):
 L.append("END")
 print(L)

test([1, 1, 1])
test([2, 2, 2])

上述程序在传入具体列表时看似正常,但存在一个潜在问题:若调用 test 函数时不传入任何参数,输出结果可能出乎意料。


def test(L=[]):
 L.append("END")
 print(L)

test()
test()

输出结果:

['END'] ['END', 'END']

函数定义时,默认参数的值在内存中已确定,即 L 指向的地址是固定的。若后续对该地址的内容进行修改(如 append),默认参数的值也会随之改变,导致多次调用时状态累积。

注意:默认参数必须指向不可变对象,以避免此类副作用。

可变参数与元组封装

可变参数

什么是可变参数?

顾名思义,可变参数允许调用函数时传递任意数量的参数。

若不使用可变参数,目前有哪些方式可以实现传入不确定个数的 list、dict、set 等?


def sum(numbers):
 total = 0
 for i in numbers:
  total += i
 return total

print(sum([1, 2, 3]))

上述写法虽能处理不确定数量的入参,但调用方不清楚入参类型,需查看函数实现才能知道应传入可迭代类型,这对调用方不够友好。

可变参数的基本格式

在定义函数时,入参前加 * 号,表示该参数为可变参数,例如:


def sum(*numbers):
 total = 0
 for i in numbers:
  total += i
 return total

print(sum(1, 2, 3))

可变参数在函数内部实际上将传入的参数封装为一个元组(tuple)。


def my_fun(*numbers):
 print(type(numbers))
 total = 0
 for i in numbers:
  total += i
 return total
 
print(my_fun(1, 2, 3))

输出结果:
<class 'tuple'>
6

命名关键字参数及其作用

命名关键字参数

我们先回顾之前最普通的入参方式——位置参数。


def person(name, age):
 print(name,age)

person("wiggin",29)

这种方式无需指定入参名字,只要位置对应即可。

与位置参数相对的是命名关键字参数,每次调用时必须指定参数名。

什么是命名关键字参数

  • 限制调用者不能按位置传递,需放在形参后面,并在前面使用星号 *(独占一个参数位)与普通形参分隔。

为什么要有命名关键字参数

  • 为了限制后续参数只能按关键字传递。这通常是因为后续形参名含义明确,显式写出有利于提高代码可读性;或者后续参数随版本迭代可能变化,强制关键字形式有利于保证跨版本兼容性。
  • 与位置参数相对的另一种方式,是每次调用的时候,都必需指定参数的名字,也就是命名关键字。

命名关键字用法


def person(name, age, *, pet):
 print(name,age,pet)

person("wiggin",29,pet="tomcat")

命名关键字使用 * 作为分隔符,* 之前的参数基于位置参数匹配,* 后面的参数在调用时必须指定其参数名。

一旦使用命名关键字,若调用时未指定参数名,会报相应的错误。


def person(name, age, *, pet):
 print(name,age,pet)

person("wiggin",29,"tomcat")TypeError: person() takes 2 positional arguments but 3 were given

TypeError: person() takes 2 positional arguments but 3 were given

* 后面的参数,同样也可以使用默认参数进行设置。


def person(name, age, *, pet="cat"):
 print(name,age,pet)

person("wiggin",29)

注意:如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符 *。

关键字参数与字典组装

关键字参数

什么是关键字参数?

关键字参数允许传入 0 个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个 dict。


def person(name, age, **kw):
 print('name:', name, 'age:', age, 'other:', kw)

person("wiggin",29,city="广州",pet="cat")

也可以使用下面的方式传参。


def person(name, age, **kw):
 print('name:', name, 'age:', age, 'other:', kw)

other_info = {"pet": "cat"}
person("wiggin",29,city="广州",**other_info)

other_info 表示把 other_info 这个 dict 的所有 key-value 用关键字参数传入到函数的 **kw 参数,kw 将获得一个 dict。注意 kw 获得的 dict 是 other_info 的一份拷贝,对 kw 的改动不会影响到函数外的 other_info。

混合使用参数的顺序规则

混合使用参数

本章之前所学习的各种类型的参数,可以在定义函数时混合使用,但是,有一个核心注意的点:混合使用时,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。

以上就是浅谈Python 参数与变量的详细内容,更多关于Python 参数与变量的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。