一、Python函数参数的基础知识
在Python中,函数参数可以分为两种,分别是位置参数和关键字参数。位置参数是指通过位置顺序传递给函数的参数,而关键字参数是通过键值对传递给函数的参数。
def func1(a, b, c): print(a, b, c) func1(1, 2, 3) # 输出1 2 3 func1(c=3, b=2, a=1) # 输出1 2 3 func1(1, c=3, b=2) # 输出1 2 3
在函数定义中,位置参数必须放在最前面,而关键字参数必须放在位置参数后面。如上述代码,函数func1有三个位置参数(a、b、c),传参时可以按照参数顺序传递,也可以通过键值对传递参数。如果混合使用位置参数和关键字参数,那么位置参数必须在前面。
二、Python函数参数的默认值
在Python中,函数参数可以设置默认值,如下所示:
def func2(a, b=2, c=3): print(a, b, c) func2(1) # 输出1 2 3 func2(1, 4) # 输出1 4 3 func2(1, c=5) # 输出1 2 5 func2(c=5, a=1) # 输出1 2 5
在上面的代码中,函数func2有三个参数,其中b和c有默认值。如果在调用函数时没有传递b和c的参数,那么默认值将被使用。如果传递了b和c的参数,那么将覆盖默认值。
三、Python函数参数的收集
有时候我们希望能够处理不定数量的参数,Python提供了两种传递不定数量参数的方法:收集参数和关键字收集参数。
1、使用*args来收集参数。
def func3(a, b, *args): print(a, b) print(args) func3(1, 2, 3, 4, 5) # 输出1 2 (3, 4, 5) func3(1, 2) # 输出1 2 ()
在上面的代码中,函数func3有三个参数,其中*args表示收集所有未匹配的位置参数。在第一次调用时,传递了5个参数,其中第一个和第二个参数被分配给a和b,而剩余的参数被收集到args列表中。在第二次调用时,只传递了两个参数,args列表为空。
2、使用**kwargs来收集关键字参数。
def func4(a, b, **kwargs): print(a, b) print(kwargs) func4(1, 2, x=3, y=4, z=5) # 输出1 2 {'x': 3, 'y': 4, 'z': 5} func4(1, 2) # 输出1 2 {}
在上面的代码中,函数func4有三个参数,其中**kwargs表示收集所有未匹配的关键字参数。在第一次调用时,传递了三个关键字参数,其中第一个和第二个参数被分配给a和b,而剩余的关键字参数被收集到kwargs字典中。在第二次调用时,没有传递任何关键字参数,kwargs字典为空。
四、Python函数参数的传递
在Python中,函数参数的传递可以是值传递或引用传递。但是,Python中所有的函数参数传递都是引用传递。
def func5(lst): lst.append(4) lst = [1, 2, 3] func5(lst) print(lst) # 输出[1, 2, 3, 4]
在上面的代码中,函数func5接收一个列表参数,向该列表添加一个元素。在主程序中,创建一个列表,并将其传递给函数func5。在函数中,通过append()函数向列表中添加一个元素。在主程序中,输出列表元素,发现列表中已经添加了一个元素,说明列表是可以被函数中修改的。
五、可以被避免的函数参数的陷阱
在函数参数的处理过程中,有一些陷阱需要避免。
1、使用可变参数作为默认参数。
def func6(a, b=[]): b.append(a) print(b) func6(1) # 输出[1] func6(2) # 输出[1, 2],而不是[2]
在上面的代码中,函数func6接收两个参数,其中b的默认值是一个空列表。每次调用函数时,如果没有传递b的值,都会使用同一个默认值列表对象。因此,在第二次调用时,输出的列表包括了前一次调用的结果。为了避免这个陷阱,可以将默认参数设置为None,并在函数中判断参数是否为None,如果是,则创建一个空列表。
def func6_fixed(a, b=None): if b is None: b = [] b.append(a) print(b) func6_fixed(1) # 输出[1] func6_fixed(2) # 输出[2]
2、改变可变参数的长度。
def func7(lst=[]): lst.append(1) return lst print(func7()) # 输出[1] print(func7()) # 输出[1, 1] print(func7()) # 输出[1, 1, 1]
在上面的代码中,函数func7返回一个被添加了一个元素1的列表对象。由于在第一次调用时,没有传递任何参数,使用了默认参数值。在第二次和第三次调用时,由于第一次调用修改了默认参数的数值,因此输出的结果不正确。为了避免这个陷阱,可以将可变参数替换为不可变类型。
def func7_fixed(lst=None): if lst is None: lst = [] lst.append(1) return lst print(func7_fixed()) # 输出[1] print(func7_fixed()) # 输出[1] print(func7_fixed()) # 输出[1]
六、总结
Python函数参数可以分为位置参数和关键字参数,可以设置默认值,还可以收集不定数量的参数。在函数参数传递过程中,所有传递的参数都是引用传递,而不是值传递。在函数参数处理过程中需要注意避免一些陷阱。