DAY14 前复盘+ 匿名函数 内置函数 面向对象编程
定义函数
只检测语法,不执行代码
函数定义的三种方式
- 有参函数
- 无参函数
- 空函数
调用函数
def f1():
return 123
f = f1()
f1()*2
lis = [f1(),2]
函数的返回值
return返回返回值,函数遇到return会终止,return可以返回任意数据类型的值,同时也可以返回多个值
函数只有在调用阶段才会接收返回值
函数的参数
形参
接收实参,具有描述意义,没有具体值
实参
具有具体的值,传参给形参
- 位置形参:从左到右一个一个接收位置实参
- 位置实参:从左到右一个一个传给形参
- 关键字实参:根据形参名传参
- 默认形参:给形参一个默认值,如果实参不对该形参传值,则使用默认值;反之,使用实参传的值
- 关键字实参必须得在位置实参后面,默认形参也必须在位置形参后面
- 一个形参只能接收一个值
def f1(x,y):
pass
f1(1,x=2) # 报错
可变长参数
- *形参:接收多余的位置实参,以元组的方式存储
- *实参:把元组打散成一个个位置实参,然后传给形参(不推荐使用,只做了解)
- **形参:接收多余的关键字实参,以字典的方式存储
- **实参:把字典打散称一个个关键字实参,然后传给形参(不推荐使用,只做了解)
- 牢记:
def f1(*args,**kwargs):
pass
# f1可以接收所有的参数
f1(1,1,2,3,3,4,5,x=2,y=5,a=8)
函数对象
def f1():
pass
- 引用
f=f1
- 作为函数返回值
return f1
- 作为函数参数传入
f2(f1)
- 容器元素
lis=[f1]
函数的嵌套
def f1():
def f2():
pass
f2() # 报错
名称空间与作用域
- 内置名称空间:存放内置的名字,如
len/eval/enumerate/bytes/max/min/sorted/map/filter....
- 全局名称空间:除了内置与局部,其他的名字都存放在全局名称空间内
- 局部名称空间:函数内部的名字都是局部名称空间,不同函数内部的名字互不干涉
- 查找顺序:从当前开始往上寻找,如果当前是局部名称空间,查找顺序为:局部--》全局--》内置
- 执行顺序:先内置(Python解释器启动的时候才会生成)--》全局(文件执行的时候才会生成)--》局部(函数调用的时候才会生成)
作用域:全局名称空间和局部名称空间中可能会存在名字相同的变量,但是这两个变量互不影响。只针对不可变数据类型,对于可变数据类型除外,尽量不要使用可变类型的这个特性,如果真的使用,可以不同的函数定义不同的变量出来。
闭包函数
def f1():
x = 10
def f2():
print(x) # 10
x = 1000
f1() # 10
print(x) # 1000
def f1():
x = 10
def f2():
print(x) # 10
return f2
f = f1() # f2
f() # f2()
- 把函数和变量一起打包拿出去了
def f1(x):
def f2():
print(x) # 10
return f2
f3 = f1(10) # f2
f3() # f2() # 10
f3() # 10
f3() # 10
f4 = f1(5)
f4() # 5
f4() # 5
装饰器
- 不改变函数体代码,并且不改变函数调用方式,它本质就是一个函数
def f1(x):
def f2():
print(x) # 10
return f2
f2 = f1()
f2() # f2()
- 完善装饰器
def login_deco(func):
def wrapper(*args,**kwargs):
login_judge = login()
if login_judge:
res = func(*args,**kwargs)
return res
return wrapper
@login_deco
def shopping():
pass
# shopping = deco(shopping)
# shopping()
三层装饰器
def sanceng(x,y):
def login_deco(func):
print(x,y)
def wrapper(*args,**kwargs):
login_judge = login()
if login_judge:
res = func(*args,**kwargs)
return res
return wrapper
return login_deco
@sanceng(10,20)
def shopping():
pass
day20
# shopping = login_deco(shopping)
# shopping()
迭代器
- 可迭代对象:具有iter方法的对象(Python中一切皆对象)
- 迭代器对对象:具有iter和next方法
- 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象(f)
三元表达式
列表推导式
字典生成式
生成器表达式
生成器
自定义的迭代器,函数内部使用yield关键,有yield关键字的函数只要调用,这个调用后的函数就是生成器
- yield:接收函数返回值,但是会继续执行函数体代码
- return:接收函数返回值,但是会终止函数
def f1():
yield 1
g = f1() # 变成生成器
for i in g:
print(i) # 1
递归
递归本质上就是函数调用函数本身,必须得有结束条件,并且在递归的过程中,问题的规模必须都不断缩小
二分搜索
def find_num(num,lis):
if len(lis) == 1 and lis[0] != num:
print('没找到')
return
mid_ind = int(len(lis) / 2) # 中间索引
mid_num = lis[mid_ind] # 中间值
if num < mid_num:
lis = lis[:mid_ind]
find_num(num,lis)
elif num > mid_num:
lis = lis[mid_ind + 1:]
find_num(num, lis)
else:
print('find')
lis = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
find_num(20,lis)
匿名函数
lamdbda 参数 : 逻辑代码
- 匿名函数使用一次就失效了,一般不单独使用,与max最大值/min最小值/sorted排序/map映射/filter过滤 连用
max(dic,key=lambda name: dic[name])
max(dic)
max(lis/se/tup)
- 内置函数(有空看一看,没空抄一抄)
面向过程编程
类似于工厂的流水线,机械式的一步一步完成一个项目,把完成步骤具体细分,这样步骤与步骤之间互不干涉
缺点:扩展性差,只要有一个步骤断了,项目就崩溃了
优点:清晰优雅