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 匿名函数、内置函数