1.函数的传参(把数据给函数)
2.函数的形参(接收函数调用传过来的数据)
传递方式:
位置传参与序列传参
关键字传参与字典关键字传参
实参的对应关系与形参的对应关系是按位置来依次对应的
说明:
实参和形参通过位置进行传递和匹配
实参个数与形参个数相同
序列传参是指在函数调用过程中,用星号* 将序列拆解后按位置进行传递的传递方式
说明:
序列传参时,序列拆解的每个元素的位置必须跟形参的位置一一对应
L = [1,2,3]
fun(*L) #传递三个参数,分别为1,2,3,相当于 fun(1,2,3)
关键字传参是指传参时,按着参数列称给形参赋值,实参跟形参按名称进行匹配
说明:
可以不按位置进行匹配传参,直接使用形参名字进行参数传递
是指实参为字典,将字符用两个星号** 拆解后进行关键字传参的传递方式
说明:
字典的键名和形参名必须一致
字典的键名必须为符合标识符命名规则的字符串
字典的键名要在形参中存在
1.函数的传参方式能够确定形参能唯一匹配到相应实参的情况下可以任意组合
2.函数的位置传参要先于关键字传参,只要前面有一个关键字字传参,后面要传的所有参数都要关键字传参
示例:
#python传参方法
#下面所有的结果都为输出:1,2,3
def fun(x,y,z):
'''传参示例'''
print(x,y,z)
#位置传参
fun(1,2,3)
#序列传参
L = [1,2,3]
fun(*L)
#关键字传参
fun(x = 1,z = 2,y = 3)
#字典关键字传参
d = dict(x = 1,y = 2,z = 3)
fun(**d)
#综合传参
l = [1,2]
fun(*l,3)
fun(*l,z = 3)
语法:
def 函数名(形参名1 = 默认参数1,形参名2 = 默认参数2,...)
作用:
让函数调用者少传递参数来调用函数,在用户没输入该对应的实参时使用默认参数
说明:
1.缺省参数必须自右至左依次存在,如果一个参数有缺省参数,则其右侧的所有参数都必须有缺省参数
2.缺省参数可以有0个,1个或多个,甚至全部都有缺省参数
示例:
#写一个函数,myadd,此函数可以传入2个,3个或者4个实参,此函数功能是计算所有实参的和
def myadd(x,y,z = 0,h = 0):
return sum([x,y,z,h])
函数的可变实参和不可变实参的传递
python中一切皆对象,函数中传递的是对象的引用,当形参指向了不同对象,实参不会改变;当形参通过传递来的引用修改了对象的内容,实参会跟着改变,因为形参和实参指向的是同一个对象。其中不仅是函数参数的传递是这样,在函数内部也是这样。当一个变量向另一个变量赋值时,给的是对象的引用,这个对象的引用,感觉相当于c语言中变量的地址,只是在python中,这个地址变量是通用的,可以指向任意类型,当你改变了这个地址,相当与python中指向了不同对象,原来变量的地址没有改变,所以原来变量指向的地址的内容没有改变。当你通过这个地址改变了地址里面的内容时,原来变量指向的地址的内容也会跟着改变。
在函数内部对变量赋值是在函数内部创建新的局部变量,此赋值语句不会改变外部变量的绑定关系
说明:
当一个可变对象通过实参传入函数内时,在函数内可以通过局部变量来操作可变对象(列表,字典,集合,字节数组)
注意:
试运行以下程序的结果是什么,为什么?
L = [1,2]
def fn(a,lst = []):
lst.append(a)
print(lst)
fn(3,L) #[1,2,3]
fn(4,L) #[1,2,3,4]
fn(5) #[5] 注意!!!!!!
fn(6) #[5,6]
fn(7) #[5,6,7]
因为在函数创建时 lst = []就已经被创建出来了,保存在函数中,所以导致后面多次调用时[]不是空的
想要修改此问题,可以使用以下方法:
def fn(a,lst = None):
if lst is None:
lst = []
lst.append(a)
print(lst)
fn(3,L) #[1,2,3]
fn(4,L) #[1,2,3,4]
fn(5) #[5]
fn(6) #[6]
fn(7) #[7]
位置形参
星号元组形参
命名关键字形参
双星号字典形参
1)位置形参
语法:
def 函数名(形参变量1,形参变量2,...):
语句块
2)星号元组形参
语法:
def 函数名(*元组形参名):
语句块
作用:
收集多余的位置参数
说明:
元组形参名一般命名为‘args’,绑定的是一个元组,星号*元组形参只能有一个
示例:
def func(*args):
print("实参个数:",len(args))
print('args =',args)
#可以传递任意一个参数
func() #无参,结果如下
#实参个数: 0
#args = ()
func(1,2,3,4,5,6,7) #任意个参数
s = "asd"
func(*s) #等同于func('a','s','d'),此处的*的作用是把s拆开
func(a = 100,b = 200) #出错
#写一个程序,mysum可以传入任意个实参的参数,此函数的功能是返回所有实参的和
def mysum(*args):
return sum(args)
3)命名关键字形参
语法:
def 函数名(*,命名关键字形参1,命名关键字形参2,...):
语句块
**作用:**
强制所有的命名关键字形参都必须用关键字传参或字典关键字传参
示例:
#1.
def func(a,b,*,c,d):
print(a,b,c,d)
#func(1,2,3,4) #error,星号元组形参后无关键字传参
func(1,2,d = 3,c = 4)
func(1,2,**{'c':2,'d',3})
#2.
def func(a,b,*args,c,d):
print(a,b,args,c,d)
#调用
func(1,2,c = 1,d = 3) #args = ()
func(1,2,4,5,6,7,c = 1,d = 3) #args = (4, 5, 6, 7)
#仿造max函数,写一个于max功能完全一样的mymax函数(要求:不允许调用内建的max函数)
如:
def mymax(...):
...
print(mymax([6,8,3,5])) #8
print(mymax(100,200)) #200
print(mymax(1,3,5,3,6,9,7)) #9
print(mymax()) #报错
#answer:
def mymax(arg1,*args):
if len(args) == 0:
max_num = arg1[0]
for i in arg1:
if i > max_num:
max_num = i
else:
max_num = arg1
for i in args:
if i > max_num:
max_num = i
return max_num
4)双星号字典形参
语法:
def 函数名(**字典形参名):
语句块
作用:
收集多余的关键字传参,全部多余的,不需要收集的参数全部连续
说明:
字典形参名一般命名为‘kwargs’,绑定的是一个字典
一个函数内字典形参最多一个,后面不能有其他参数
示例:
def func(**kwargs):
print("关键字传参的个数为:",len(kwargs))
print("kwargs = ",kwargs)
func(name = "name1",age = 12)
#关键字传参的个数为: 2
#kwargs = {'name': 'name1', 'age': 12}
def func(*,a,b,**kwargs):
print("多余的关键字传参的个数为:",len(kwargs))
print("kwargs = ",kwargs)
func(a = 2,b = 3,name = "name1",age = 12)
#多余的关键字传参的个数为: 2
#kwargs = {'name': 'name1', 'age': 12}
位置形参,缺省参数,星号元组形参,双星号字典形参可以混合使用
函数形参自左向右的定义顺序为:
位置形参
星号字典形参
命名关键字形参
双星号字典形参
示例:
def fn(a,b,*args,c,**kwargs):
pass
fn(1,2,3,4,c = 1,d = 2,e = 3)
函数的不定长参数:
有两种:星号元组形参,双星号字典形参
用不定长参数可以接收任意的传参
如:
def fn(*args,**kwargs):
print(args,kwargs)
#此函数可以传递任意参数