6.1 函数介绍
1 为什么要有函数?没有函数带来的困扰?
组织结构不清晰,可读性差
代码冗余
可扩展性差
2 什么是函数
具备某一个功能的工具---》函数
事先准备工具-》函数的定义
拿来就用、重复使用-》函数的调用
ps:先定义后调用
3 函数的分类:
内置函数:len,max(10,11),help(函数名)
自定义函数:def
语法:
def 函数名(参数1,参数2,...):
"""注释"""
函数体
6.2 函数的定义
定义函数阶段都发生了什么事:只检测语法,不执行代码
定义阶段
sex='male'
defauth():
sex
name=input('name>>:').strip()
password=input('password>>:').strip()if name =='egon' and password == '123':print('login successfull')else:print('user or password err')#调用阶段
auth()
函数的使用:先定义后调用
#定义阶段
deffoo():print('from foo')
bar()defbar():print('from bar')#调用
foo()
定义函数的三种形式
第一种:无参函数
defauth():
name=input('name>>:').strip()
password=input('password>>:').strip()if name =='egon' and password == '123':print('login successfull')else:print('user or password err')
第二种:有参函数
defauth(name,password):if name =='egon' and password == '123':print('login successfull')else:print('user or password err')definteractive():
name=input('name>>:').strip()
password=input('password>>:').strip()
auth(name,password)
interactive()
第三种:空函数
defauth():pass
defput():pass
6.3 函数的调用
函数的调用:函数名加括号
1 先找到名字
2 根据名字调用代码
6.3.1 函数的返回值
return的特点:
1、函数内可以有多个return,但是只能执行一次return
2、执行return函数就立刻结束,并且return的后值当做本次调用的结果返回
3、返回的值没有类型限制
defmy_max(x,y):if x >=y:return x #只能执行一次return
else:return y
return返回值的个数
1: 没有return:默认返回None
2:return 值:值本身
3:return 多个值:返回一个元组
6.3.2函数调用的三种形式
defmy_max(x,y):if x >=y:returnxelse:return y
1、语句形式
res1=my_max(1,2)
2、表达式形式
res2=my_max(1,2)*10
3、当中另外一个函数的参数
res3=my_max(my_max(1,2),3)
6.4 函数的参数
函数的参数分类两种:
形参:在定义阶段括号内指定的参数,相当于变量名
实参:在调用阶段括号内传入的值称之为实参,相当于值
#在调用阶段,实参的值会绑定给形参,在调用结束后解除绑定
def foo(x,y): #x=1,y=2
print(x,y)
foo(1,2)
6.4.1 位置参数
位置参数:按照从左到右的顺序依次定义的参数
位置形参:必须被传值,多一个少一个都不行
位置实参:与形参一一对应传值
deffoo(x,y):print(x,y)
foo(2,1)
6.4.2 关键字参数
关键字参数:在函数调用时,按照key=value的形式定义的实参
特点:指名道姓地给形参传值,不再依赖与位置
foo('egon',18,'male')
foo(sex='male',age=18,name='egon') #关键字参数
foo('egon',sex='male',age=18,name='egon') #关键字实参必须在位置实参的后面
注意:
1、 关键字实参必须在位置实参的后面
2、 不能为同一个参数赋值多次
6.4.3 默认参数
默认参数:在函数定义阶段,就已经为形参赋值了
特点:定义阶段已经有值意味着调用阶段可以不用传值
位置参数通常用于经常变化的参数,而默认参数指的是大多数情况下都一样的
def foo(x,y=1): #y有默认值
print(x,y)
foo(1,2) #位置实参
foo(y=3,x=1) #关键字参数
foo(111)
foo(x=1111) #为给y传参
注意:
1、默认参数必须放到位置形参的后面
def register(name,sex='male',age,): #报错
print(name,age,sex)
2、默认参数的值只在定义时被赋值一次
3、默认的参数的值通常应该是不可变类型
6.4.5 可变长参数
可变长参数:在调用函数时,实参值的个数不固定
实参的形式有:位置实参和关键字实参,
形参的解决方案:* , **
#*args的用法
def foo(x,y,*args): #z=(3,4,5,6)
print(x,y)print(args)
foo(1,2,3,4,5,6)
foo(1,2,*[3,4,5,6]) #foo(1,2,3,4,5,6)
foo(*[1,2,3,4,5,6]) #foo(1,2,3,4,5,6)
#**kwargs
def foo(x,y,**kwargs): #kwargs={'c':5,'a':3,'b':4}
print(x,y)print(kwargs)
foo(y=2,x=1,a=3,b=4,c=5)
foo(y=2,**{'c':5,'x':1,'b':4,'a':3}) #foo(y=2,a=3,c=5,b=4)
deffoo(name,age):print(name,age)
foo(**{'name':'egon','age':18})
foo({'name':'egon','age':18})
6.4.6 命名关键字参数
命名关键字参数:指的是定义在*后的参数,该参数必须被传值(除非有它有默认值),而且必须按照key=value的形式传值
def foo(x,y,*args,m=100000,n):print(x,y)print(args)print(m,n)
foo(1,2,3,n=4,)def foo(x,y,*,m=100000,n):print(x,y)print(args)print(m,n)
foo(1,2,3,n=4,)
6.5 函数对象
函数是第一类对象:指的是函数可以当做数据传递
1、可以被引用 x=1,y=x
deffunc(x,y):print(x,y)
f=func #获得函数名
f(1,2) #调用函数
2、可当做函数的参数传入
deffoo():print('from foo')def bar(func): #函数为参数
#print(func)
func()
bar(foo)
3、可以当做函数的返回值
deffoo():print('from foo')defbar():return foo #返回函数
f=bar()
f()
4、可以当做容器类型的元素
deffoo():print('from foo')defbar():returnfoo
l=[foo,bar] #函数为列表元素
print(l)
l[0]()#调用函数
利用该特性,取代多分支的if
defget():print('get')defput():print('put')defls():print('ls')defauth():print('auth')
func_dic={'get':get,'put':put,'ls':ls,'auth':auth
}#func_dic['put']()
cmd = input('>>:').strip()if cmd infunc_dic:
func_dic[cmd]()
6.6 函数嵌套
6.6.1函数的嵌套调用
defmy_max(x,y):if x >=y:returnxelse:returnydefmy_max4(a,b,c,d):
res1=my_max(my_max(a,b),c) #函数嵌套调用
res2=my_max(res2,d)return res2
6.6.2函数的嵌套定义
deff1():deff2():print('from f2')deff3():print('from f3')
f3()#print(f2)
f2()
f1()#f2
7 名称空间与作用域、闭包函数、 装饰器
8 迭代器、 生成器、 面向过程编程
9 三元表达式、列表推导式和生成器表达式
10 递归调用、 二分法
11 匿名函数、内置函数