Python函数参数传递是定义和调用函数时的核心操作,不同的参数传递方式适配不同的业务场景,理解其规则能帮助我们写出更灵活的函数代码。Python的参数传递本质是对对象的引用传递,具体表现会根据传递的对象类型有所不同,同时支持多种参数定义和调用形式。
基础参数传递类型
位置参数
位置参数是最常见的参数传递方式,调用函数时按照参数定义的顺序依次传入对应的值,顺序和数量都必须匹配。
# 定义计算两个数之和的函数,a和b是位置参数
def add(a, b):
return a + b
# 调用时按照顺序传入参数,1对应a,2对应b
result = add(1, 2)
print(result) # 输出3
关键字参数
关键字参数允许调用函数时通过参数名指定传入的值,不需要严格按照定义顺序,可读性更强,尤其适合参数较多的情况。
def user_info(name, age, city):
print(f"姓名:{name},年龄:{age},城市:{city}")
# 使用关键字参数传递,顺序可以和定义顺序不同
user_info(city="北京", name="张三", age=25)
默认参数
默认参数是指在定义函数时为参数指定默认值,调用时如果没有传入该参数,就使用默认值,减少重复传参的操作。
# 定义函数时为city参数设置默认值"上海"
def user_info(name, age, city="上海"):
print(f"姓名:{name},年龄:{age},城市:{city}")
# 不传入city参数,使用默认值
user_info("李四", 30) # 输出姓名:李四,年龄:30,城市:上海
# 传入city参数,覆盖默认值
user_info("王五", 28, "广州") # 输出姓名:王五,年龄:28,城市:广州
注意默认参数必须放在非默认参数的后面,否则会报语法错误。
可变参数传递
可变位置参数
如果函数需要接收不定数量的位置参数,可以在参数前加*,这样所有多余的位置参数会被打包成一个元组传入。
# *args表示可变位置参数,接收多余的位置参数组成元组
def sum_all(*args):
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3)) # 输出6
print(sum_all(10, 20, 30, 40)) # 输出100
可变关键字参数
如果需要接收不定数量的关键字参数,可以在参数前加**,所有多余的关键字参数会被打包成一个字典传入。
# **kwargs表示可变关键字参数,接收多余的关键字参数组成字典
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="赵六", age=22, hobby="跑步")
# 输出:
# name: 赵六
# age: 22
# hobby: 跑步
参数传递的引用机制
Python的参数传递是对象引用传递,当传递不可变对象(如整数、字符串、元组)时,函数内部修改参数不会影响外部变量;当传递可变对象(如列表、字典、集合)时,函数内部修改参数会影响外部变量。
def modify_data(num, lst):
num += 1 # 修改不可变对象,不影响外部
lst.append(4) # 修改可变对象,会影响外部
a = 10
b = [1, 2, 3]
modify_data(a, b)
print(a) # 输出10,a没有被修改
print(b) # 输出[1, 2, 3, 4],b被修改了
参数传递的常见组合规则
在实际定义函数时,参数顺序通常为:位置参数 → 默认参数 → 可变位置参数 → 可变关键字参数,这样的顺序符合Python的语法规范,避免调用时出现歧义。
# 符合规范的参数定义顺序
def func(a, b, c=10, *args, **kwargs):
print(f"a:{a}, b:{b}, c:{c}")
print(f"args:{args}")
print(f"kwargs:{kwargs}")
func(1, 2, 3, 4, 5, name="测试", age=20)
# 输出:
# a:1, b:2, c:3
# args:(4, 5)
# kwargs:{'name': '测试', 'age': 20}