Python 函数 —— 定义,参数,参数解构
函数
函数
数学定义:y = f(x), y是x的函数,x是自变量。 y = f(x0,x1,x2,...,xn)
python函数:
- 由 若干语句组成的语句块、函数名称、参数列表 构成,它是组织代码的最小单元
- 完成一定的功能
函数的作用
1.结构化编程对代码的最基本的封装,一般按照功能组织一段代码
2.封装的目的是为了复用,减少沉余代码
3.代码更加简洁美观,可读易懂
函数的分类
内建函数: 如 max(),reverse()等
库函数: 如 math.ceil()等
自定义函数:
函数的定义,调用
def 语句定义函数
def 函数名(参数列表):
函数体(代码块)
[ return 返回值]
- 函数名就是标识符,命名要求跟标识符一样
- 语句块必须缩进,约定4个空格
- python的函数没有return时,隐式会返回一个None值
- 定义中的参数列表成为形式参数,只是一种符号表达,简称形参(类似于一种占位符)
函数调用
1.函数定义 只是声明了一个函数,它不会被执行,需要调用
2.调用的方式,就是函数名加上(),括号内写上参数
3.调用时写得参数是实际参数,是实实在在传入的值,简称实参
函数举例
defadd(x,y):result=x+yreturnresultout=add(4,5)print(out)
上面只是一个函数的定义,有一个函数叫做add,接收2 个参数
计算的结果,通过返回值返回
调用通过函数名add加2 个参数,返回值可使用变量接收
定义需要在调用钱,也就是说调用时,已经被定义过了,否则抛出Name Errory异常
函数式可调用的对象,callable()
函数参数
参数调用时传入的参数要和定义的个数相匹配(可变参数例外)
位置参数:
def f(x,y,z) 调用使用 f(1,3,5)
按照参数定义顺序传入实参
关键字参数
def f(x, y ,z) 调用使用 f(x =1, y = 3, z = 4)
使用形参的名字来传入实参的方式,如果使用了形参名字,那么传参顺序就可以和定义顺序不同
传参
要求位置参数必须在关键字参数之前传入,位置参数是按位置对应的
函数参数默认值
参数默认值(缺省值)
定义时,在形参后面跟上一个值
defadd(x=4,y=5):returnx+y
作用
1.参数的默认值可以在未传入足够的实参的时候,对没有给定的参数复制为默认值
2.参数非常多的时候,并不需要用户每次都输入所有的参数,简化函数调用
举例:
定义一个函数login,参数名称为 host、port、username、password
deflogin(host="127.0.0.1",port="8080",username="123",password="123"):print('{}:{}@{}/{}'.format(host,port,username,password))login()login('127.0.0.1',80,"tom",'tom')login('127.0.0.1',username='root')login('localhost',port=80,password='com')login(port=80,password='123',host='www')
可变参数
问题:有多个数,需要累加求和
defadd(nums):sum=0forxinnums:sum+=xreturnsumadd([1,3,5])、add((2,4,6))
传入一个可迭代对象,迭代元素求和
可变参数
一个形参可以匹配的任意个参数
位置参数的可变参数书:
有多个数,需要累加求和:
defadd(*nums):sum=0print(type(nums))forxinnums:sum+=xprint(sum)add(3,6,9)#调用执行结果:<class'tuple'>18
1.在形参前使用 * 表示该形参是可变参数,可以接收多个实参
2.收集多个实参形成一个tule
关键字参数的可变参数:
配置信息打印
defshowconfig(**kwargs):print(kwargs)fork,vinkwargs.item():print('{}={}'.format(k,v))showconfig(host='127.0.0.1',port="8080",username='123',password='123')执行结果:<class'dict'>{'host':'127.0.0.1','port':'8080','username':'123','password':'123'}host=127.0.0.1port=8080username=123password=123
1.形参前使用**符号,表示看可以接收多个关键字参数
2.收集的实参名称和值收集 形成一个字典
可变参数混合使用
总结
1.有位置可变参数和关键字可变参数
2.位置可变参数在形参前使用 一个星号 *
3.关键字可变参数在形参前面使用 两个星号 **
4.位置可变参数和关键字可变参数都可以收集果干个实参,位置可变参数收集成一个 tuple ,关键字可变参数收集形成一个dict
举例:
deffn(x,y,*args,**kwargs):print(x,y)print(args)print(kwargs)fn(3,5,9,10,a=1,b='python')->OKfn(3,5)->OKfn(3,5,7)->OKfn(3,5,a=1,b='python')->OKfn(7,9,y=5,x=3,b='python')->NG#错误,7和9分别赋给了x,y,又y=5,x=3,重复了
举例
deffn(*args,x,y,**kwargs):print(x,y)print(args)print(kwargs)fn(3,5,9,10,a=1,b='python')->NGfn(3,5)->NGfn(3,5,7)->NGfn(3,5,a=1,b='python')->NGfn(7,9,y=5,x=3,b='python')->Ok
keyword-only 参数
keyword-only参数(python3加入)
如果在一个星号参数后,或者一个位置可变参数后,出现的普通参数,实际上已经不是普通的参数了,而是keyword-only参数
deffn(*args,x):print(x)print(args)fn(3,5)->NGfn(3,5,7)->NGfn(3,5,x=7)->OK
args可以看做已经接活了所有的位置参数,x不适用关键字参数就不可能拿到实参
思考:def fn(**kwargs,x)可以嘛???
举例:
deffn(**kwargs,x):print(x)print(kwargs)
直接报语法错误:
可以理解为kewargs会接货所有的关键字参数,就算写了x=5,x也永远得不到这个值,所以语法错误
keyword-only参数的另一种形式
deffn(*,x,y):print(x,y)fn(x=5,y=6)
*号之后,普通的形参都变成了必须给出的keyword-only参数
可变参数和参数默认值
举例:
deffn(*args,x=5):print(x)print(args)fn()->OKfn(5)->OKfn(x=6)->Okfn(1,2,3,x=10)->Ok
举例:
deffn(y,*args,x=5):print('x={},y={}'.format(x,y))fn()->NGfn(5)->OKfn(x=6)->NGfn(1,2,3,x=10)->Okfn(y=17,2,3,x=10)->NG#位置传参放在了keyword传参后面了,要注意fn(1,2,y=3,x=10)->NGy传参重复了
x 是keyword-only参数
举例:
deffn(x=5,**kwargs):print('x={}'.format(x))print(kwargs)fn()->OKfn(5)->OKfn(x=6)->OKfn(y=3,x=10)->OKfn(3,y=10)->OK
函数参数
参数规则
参数列表参数一般顺序:
普通参数 -> 缺省参数 -> 可变位置参数 -> keyword-only参数(可带缺省值) -> 可变关键字参数
deffn(x,y,*args,m=4,n,**keargs):print(x,y,m,n)print(args)print(kwargs)
参数规则举例:
defconnect(host='localhost',port='3306',user='admin',password='admin',**kwargs):print(host,port)print(user,password)print(kwargs)connect(db='cmdb')connect(host='192.168.1.123',db='cmdb')connect(host='192.168.1.123',db='cmdb',password='mysql')
参数解构
举例:
加法函数
defadd(x,y):returnx+yadd(4,5)add((4,5))t=(4,5)add(t[0],t[1])add(*t)或add(*(4,5))add(*[4,5])add(*{4,6})add(*range(1,3))
参数解构:
1.给函数提供实参的时候,可以在集合类型前使用 * 或者 **, 把集合类型的结构解开,提取所有元素作为函数的实参
2.非字典类型使用 * 解构成 位置参数
3.字典类型使用 ** 解构成 关键字参数
4.提取出来的元素数目要和参数的要求匹配,也要和参数的类型匹配
defadd(x,y):returnx+yadd(*(4,5))add(*[4,5])add(*{4,5})->OKd={'x':5,'y':6}add(**d)->OKadd(**{'a':5,'b':6})->解构后为(a=5,b=6)没有x,yNGadd(*{'a':5,'b':6})->解构后('a','b')OK
参数解构 和 可变参数
给函数提供实参的时候,可以在集合类型前使用* 或者 **,把集合类型的结构解开,提取出所有元素作为函数的实参
defadd(*iteable):result=0forxiniterable:result+=xreturnresultadd(1,2,3)->OKadd(*[1,2,3])->OKadd(*range(10))->OKadd(range(10))->NG
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。