python 函数
6.1 函数介绍
1 为什么要有函数?没有函数带来的困扰?
组织结构不清晰,可读性差
代码冗余
可扩展性差
2 什么是函数
具备某一个功能的工具---》函数
事先准备工具-》函数的定义
拿来就用、重复使用-》函数的调用
ps:先定义后调用
3 函数的分类:
内置函数:len,max(10,11),help(函数名)
自定义函数:def
语法:
def 函数名(参数1,参数2,...):
"""注释"""
函数体
6.2 函数的定义
定义函数阶段都发生了什么事:只检测语法,不执行代码
定义阶段
sex='male' def auth(): 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()
函数的使用:先定义后调用
#定义阶段 def foo(): print('from foo') bar() def bar(): print('from bar') #调用 foo()
定义函数的三种形式
第一种:无参函数
def auth(): name=input('name>>: ').strip() password=input('password>>: ').strip() if name =='egon' and password == '123': print('login successfull') else: print('user or password err')
第二种:有参函数
def auth(name,password): if name =='egon' and password == '123': print('login successfull') else: print('user or password err') def interactive(): name=input('name>>: ').strip() password=input('password>>: ').strip() auth(name,password) interactive()
第三种:空函数
def auth(): pass def put(): pass
6.3 函数的调用
函数的调用:函数名加括号
1 先找到名字
2 根据名字调用代码
6.3.1 函数的返回值
return的特点:
1、函数内可以有多个return,但是只能执行一次return
2、执行return函数就立刻结束,并且return的后值当做本次调用的结果返回
3、返回的值没有类型限制
def my_max(x,y): if x >= y: return x #只能执行一次return else: return y
return返回值的个数
1: 没有return:默认返回None
2:return 值:值本身
3:return 多个值:返回一个元组
6.3.2 函数调用的三种形式
def my_max(x,y): if x >= y: return x else: 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 位置参数
位置参数:按照从左到右的顺序依次定义的参数
位置形参:必须被传值,多一个少一个都不行
位置实参:与形参一一对应传值
def foo(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) def foo(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
def func(x,y): print(x,y) f=func #获得函数名 f(1,2) #调用函数
2、可当做函数的参数传入
def foo(): print('from foo') def bar(func): #函数为参数 # print(func) func() bar(foo)
3、可以当做函数的返回值
def foo(): print('from foo') def bar(): return foo #返回函数 f=bar() f()
4、可以当做容器类型的元素
def foo(): print('from foo') def bar(): return foo l=[foo,bar] #函数为列表元素 print(l) l[0]() #调用函数
利用该特性,取代多分支的if
def get(): print('get') def put(): print('put') def ls(): print('ls') def auth(): print('auth') func_dic={ 'get':get, 'put':put, 'ls':ls, 'auth':auth } # func_dic['put']() cmd = input('>>: ').strip() if cmd in func_dic: func_dic[cmd]()
6.6 函数嵌套
6.6.1函数的嵌套调用
def my_max(x,y): if x >= y: return x else: return y def my_max4(a,b,c,d): res1=my_max(my_max(a,b),c) #函数嵌套调用 res2=my_max(res2,d) return res2
6.6.2函数的嵌套定义
def f1(): def f2(): print('from f2') def f3(): print('from f3') f3() # print(f2) f2() f1() # f2
7 名称空间与作用域、闭包函数、 装饰器
http://www.cnblogs.com/snailgirl/p/8125021.html
8 迭代器、 生成器、 面向过程编程
http://www.cnblogs.com/snailgirl/p/8125032.html
9 三元表达式、列表推导式和生成器表达式
http://www.cnblogs.com/snailgirl/p/8125037.html
10 递归调用、 二分法
http://www.cnblogs.com/snailgirl/p/8125041.html