Python 函数参数-7.30笔记
程序员文章站
2022-05-04 23:54:25
本周计划: 1. 函数的基础 1.1 定义与调用函数 1.2 函数参数的使用 1.3 函数对象 1.4 函数的嵌套使用 函数递归 1.5 名称空间与作用域(******) 1.6 匿名函数\内置函数 2. 函数高级 1.7 闭包函数\装饰器 1.8 迭代器\生成器 1.9 三元表达式,列表生成式,生 ......
本周计划:
1. 函数的基础
1.1 定义与调用函数
1.2 函数参数的使用
1.3 函数对象
1.4 函数的嵌套使用
函数递归
1.5 名称空间与作用域(******)
1.6 匿名函数\内置函数
2. 函数高级
1.7 闭包函数\装饰器
1.8 迭代器\生成器
1.9 三元表达式,列表生成式,生成器表达式
1.10 面向过程编程
上节课复习:
1. 什么是函数
在程序中函数就是具备某一功能的工具
2. 为何用函数
为了解决以下问题:
1. 程序的组织结构不清晰,可读性差
2. 代码冗余
3. 扩展性差
3. 如何用函数
1. 必须原则: 先定义,后调用
2. 定义函数语法:
def 函数名(参数1,参数2,.....):
'''
文档注释
:param 参数1:
:param 参数2:
:return:
'''
Ps: 定义函数时,只检测语法不执行代码
4. 调用函数的语法:
函数名(值1,值2,....) #定义时无参,调用时也无需传入参数
ps: 调用函数时,会执行函数体的代码块
今日内容:
1. 函数的参数(*****)
1.定义函数的三种形式
1.1 无参函数
def foo():
print('from foo')
foo()
1.2 有参函数
def bar(x,y):
print(x,y)
bar(1,2)
1.3 空函数
def func():
pass
2.调用函数的三种形式
2.1 语句形式
def foo():
print('from foo')
foo() #语句形式
2.2 表达式形式
def foo(x,y):
res = x + y
return res
res = foo(1,2) #表达式形式
res1 = foo(1,2)*100
print(res1)
2.3 可以当做参数传给另一个函数
def max2(x,y):
if x > y:
return x
else:
return y
函数的返回值需要注意:
1. 返回值没有类型限制
2. 返回值没有个数限制
返回1个值: 调用函数拿到的结果就是一个值
返回多个值:调用函数拿到的结果就是一个元组
返回0个值,或者不写return: 调用函数拿到的结果就是Nong
return关键字:
return是函数结束的标志,函数内可以有多个return,但只要执行一次,整个函数就结束
2. 函数参数的使用:
1. 函数的参数分为两大类:
1.1 形参:
指的是在定义函数阶段括号内指定的变量名称之为形参,即形参本质就是变量名
1.2 实参:
指的是在调用函数阶段括号内传入的值,即实参本质就是"值"
1.3 形参与实参的关系:
在调用函数时,会将实参(值)赋值(绑定)给形参(变量名),这种绑定关系在函数调用时临时生效,在调用结束后就失效了
2. 形参与实参的具体分类:
2.1 位置参数:
2.1.1 位置形参:
在定义函数阶段按照从左到右的顺序依次定义的形参,称之为位置形参
注意:
但凡按照位置定义的形参,必须被传值,多一个不行,少一个也不行
2.1.2 位置实参:
在调用函数阶段按照从左到右的顺序依次传入的值,称之为位置实参
注意:
但凡按照位置定义的实参,会与形参一一对应
2.2 关键字参数:
2.2.1 关键字实参:
在调用函数阶段,按照key=value的形式指名道姓地为形参传值
注意:
1.可以完全打乱顺序,但仍然能指名道姓为指定的形参传值
2.可以混合使用位置实参和关键字实参,但是必须注意:
2.1 位置实参必须放到关键字实参前面
2.2 不能对一个形参重复赋值
2.3 默认参数:
指的是在定义函数阶段,就已经为某个形参赋值了,该形参称之为有默认值的形参,简称默认形参
注意:
1. 在定义阶段就已经被赋值,意味着在调用阶段可以不用为其赋值
2. 位置形参应该放到默认形参前面
3.默认参数的值在函数定义阶段就已经固定死了
位置形参vs默认形参:
对于大多情况下传的值都不相同,应该定义成位置形参
对于大多情况下传的值都相同,应该定义成默认形参
3. 可变长度的参数:
站在实参的角度,参数长度可变指的是在调用函数时,传入的实参值的个数不固定
而实参的定义方式无非两种:位置实参\关键字实参,对应着形参也必须有两种解决方案*与**,来分别应对溢出的位置实参与关键字实参
1. 在形参中带*:
会将调用函数时溢出位置实参保存成元组的形式,然后赋值*后的变量名
def foo(x,y,*z): #z=(3,4,5,6)
print(x,y,z)
foo(1,2,3,4,5,6)
2 在形参中带**:
会将调用函数时溢出关键字实参保存成字典的形式,然后复制**后的变量名
def foo(x,y,**z): #z={'z':3,'a':1,'b':2}
print(x,y,z)
foo(1,y=2,a=1,b=2,c=3)
3.在实参中带*:
但凡在实参中带*的,在传值前都先将其打散成位置实参,再进行赋值
def foo(x,y,*z): #z=(3,4,5,6)
print(x,y,z)
foo(1,*[2,3,4,5,6]) #foo(1,2,3,4,5,6)
4.在实参中带**:
但凡在实参中带**的,在传值前都先将其打散成关键字实参,再进行赋值
def foo(x,y,**z): #z={'a':100,'b':200}
print(x,y,z)
foo(1,**{'a':100,'b':200,'y':111}) #foo(1,b=200,a=100,y=111)
def foo(x,y,z):
print(x,y,z)
foo(**{'y':111,'x':222,'z':333}) #foo(z=333,x=222,y=111)
5.在形参中带*与**的,*后的变量名应该为args,**后跟的变量名应该是kwargs
def foo(*args,**kwargs): #args=(1,2,3,4,5) kwargs={'a':1,'b':2,'c':3}
print(args)
print(kwargs)
foo(1,2,3,4,5,a=1,b=2,c=3)
def bar(x,y,z):
print(x,y,z)
def wrapper(*args,**kwargs): #args=(1,2,3,4,5,6) kwargs={'a':1,'b':2,'c':3}
bar(*args,**kwargs)
#bar(*(1,2,3,4,5,6),**{'a':1,'b':2,'c':3}) #bar(1,2,3,4,5,6,a=1,b=2,c=3)
wrapper(1,2,3,4,5,6,a=1,b=2,c=3)
6.!!!!!!!当我们想要将传给一个函数的参数格式原方不动地转嫁给其内部的一个函数,应该使用下面这种形式
def bar(x,y,z):
print(x,y,z)
def wrapper(*args,**kwargs): #args=(1,2) kwargs={'z':3}
bar(*args,**kwargs)
#bar(*(1,2),**{'z':3}) #bar(1,2,z=3)
wrapper(1,2,z=3) # 虽然调用的是wrapper,但是要遵循的确是bar的参数标准
7.命名关键字参数:
放到*与**之间的参数称之为命名关键字参数
注意:
命名关键字参数必须按照key=value的形式传值
2. 函数对象
3. 函数的嵌套
4. 名称空间与作用域