1.定义函数
定义:函数是指将一组语句的集合通过一个函数名封装起来,想要执行这个函数,只需调用其函数名即可。
# 定义函数的语法 def 函数名(参数1, 参数2,...): """文档描述""" 函数体 return 值 ''' 1.def:定义函数的关键字 2.函数名:函数名是对函数体代码的引用。函数的命名应该反映出函数的功能; 3.括号:括号内定义参数,参数可有可无,且不需要指定参数类型; 4.冒号:括号后要加冒号,然后在下一行开始缩进编写函数体的代码; 5."""文档描述""": 描述函数功能,参数介绍等信息的文档,非必要,但是建议加上,从而增强函数的可读性; 6.函数体:由语句和表达式组成; 7. return值:定义函数的返回值,return是可有 可无的。 '''
补充:
1).函数体中的代码定义只检测语法是否正确,不会执行代码。
2).可以通过变量名找到变量对应的值,也可以通过 函数名+括号 来找到函数体所对应的代码并执行。
2.函数的使用原则
函数的使用应该要分为两个明确的阶段:
1).定义阶段:只检测函数的语法,不执行函数体的代码。
2).调用阶段:会触发函数体代码的执行。
3.函数的定义定义与调用
(1)函数定义的三种形式
1).有参函数 def func (x): #括号里面有参数 pass func(1) 2).无参函数 def func (): #括号里面没有参数 pass func() 3).空函数 def func (): #括号里面没有参数 pass
(2)函数调用的三种形式
func() # 语句形式
def max2(x,y): if x > y: return x else: return y res=max2(10,20)*12 # 为表达式 res=max2(max2(10,20),30) # 可以将函数的调用当作参数传给另外一个函数用 print(res)
4.函数的返回值
函数的返回值没有类型限制,函数的返回值也没有个数限制。
(1)返回多个值:多个返回值用逗号隔开,返回的是元组形式。
def func() print('from fune') reture 1,1.1,'hello',[1,2] res = func() print(res,type(res)) #(1, 1.1, 'hello', [1, 2, 3]) <class 'tuple'>
(2)返回一个值:返回的就是该值本身。
def func(): return 123 res=func() print(res,type(res)) # 123 <class 'int'>
(3)返回0个值或者干脆没有return:返回none
def func(): return res=func() print(res) #none
补充:
1).return除了有返回值的功能,还有结束函数执行的功能。
2).函数内可以多个return,但只要执行一次,整个函数就立即结束,并且将return后的值返回。
函数参数的使用
形式参数(形参):在定义函数阶段,括号内定义的参数或变量名称为形参。形参只在函数内部有效。
实际参数(实参):在调用函数阶段,括号内传入的值或变量值称为实参。实参可以是任意类型的量,在调用函数时,实参必须要有确定的值。
补充:在调用函数阶段会将实参的值(值)绑定给形参(变量名),这种绑定关系只在调用函数时生效,在函数执行完毕后就会解除绑定。
def func(x,y) #形参 res = x**y return res c = func(a,b) #实参 print(c)
1.参数的细分
(1)位置参数:在定义阶段,按照从左到右的顺序依次定义的形参称之为位置形参。
特点:但凡是按照位置定义的形参,必须被传值,多一个少一个都不行。
(2)位置实参:在调用阶段,按照从左到右的顺序依次传入的值称之为位置实参。
特点:但凡是按照位置定义的实参,必须被传值,多一个少一个都不行。
2.关键字形参
在调用阶段,按照key=value的形式定义的实参称之为关键字实参。
特点:可以完全打乱顺序,但仍然能为指定的形参传值(总结:指名道姓的为指定的形参传值)
def func(x,y,z): print(x,y,z) func(x=1,y=2,z=3) # 输出为1 2 3 func(1,2,3) # 输出为1 2 3 func(z=3,y=2,x=1) # 输出为1 2 3
实参的形式可以是位置实参与关键字实参混合使用,但是必须遵循以下原则:
(1)位置实参必须放在关键字实参面前
(2)不能对同一个形参重复传播
def func(x,y,z): print(x,y,z) func(1,z=3,y=2) #输出1 2 3 func(z=3,1,y=2) #错误 func(1,z=3,x=2,y=3) #错误
3.默认形参
在定义阶段,就己经为形参赋值,该形参称之为默认实参。
特点:(1)定义阶段就已经有值,意味着调用阶段可以不用传值
(2)位置形参必须放到默认形参的面前
(3)默认形参的值在函数定义阶段已经固定死了,定义阶段之后的改动不会影响该值
(4)默认形象的值通常应该是不可变的类型。
4.可变长参数:
可变长实参:指的是在调用阶段,实参值个数是不固定的。
实参一般只有两种(位置实参,关键字实参),对应着形参也必须要有两种解决方案来分别
(1)*的用法
在形参前加*:*会将溢出的位置实参存成元组的形式,然后赋值给*后的形参名
def func(x,y,*z): # print(x,y,z) func(1,2,3,4,5) #3.4.5是属于溢出的位置
在实参前加*:但凡碰到实参中带*的,先将实参打散成位置实参再与形参做对应
def func(x,y,z): print(x,y,z) func(1,2,[3,4,5]) func(*[1,2,3,4,5]) #等价于func(1,2,3,4,5) 结果是错误 func(*[1,2,3]) #等价于func(1,2,3) 结果是1 2 3
(2)**的用法
在形参前加**:**会将溢出的关键字实参存成字典的形式,然后赋值给**后的形参名。
def func(x,y,**z): #z={'b':2,'a':1} print(x,y,z) func(1,y=2,a=1,b=2) #结果是1 2 {'a': 1, 'b': 2}
在实参前加**:但凡碰到实参中带**的,先将实参打散成关键字实参再与形参做对应
def func(x,y,z): print(x,y,z) func(1,**{'y':2,'z':3}) #等价于func(1,z=3,y=2) func(1,**{'a':2,'y':333,'z':3}) #等价于func(1,a=2,y=333,z=3) # 错误
(3)*与**的应用
def index(name,age,sex): print('index=====>',name,age,sex) # 会将wrapper函数接收的参数格式原封不动地转嫁给其内部的index函数,必须要遵循的是index的参数规则 def wrapper(*args,**kwargs): #args=('egon',) kwargs={'sex':'male','age':18} print(args) print(kwargs) index(*args,**kwargs) #index(*('egon',),**{'sex':'male','age':18}) #index('egon',sex='male',age=18) # wrapper(1,2,3,4,5,a=1,b=2,c=3) wrapper('egon',sex='male',age=18)