内容目录
- 装饰器
- 推导式
内容回顾
1.函数:
-
参数
-
def(a1,a2):pass
-
def(a1,a2=None):pass 默认参数推荐用不可变类型,慎用可变类型。
-
def(*args,**kwargs):pass
-
注意:位置参数 > 关键字参数
-
面试题:
-
函数可以做参数【知识点】
def func(arg): arg() def show(): pass func(show)
-
函数的参数传递的是什么?【内存地址 = 引用 or 值】
v = [11,2,33,4] def func(arg): print(id(arg)) #列表内存地址 print(id(v)) #列表内存地址 func(v) #其打印的都是列表的内存地址,表示传递的都是内存地址
-
*args和**kwargs的作用
-
-
-
返回值
-
常见数据类型可以返回
-
函数也可以返回
def func(): def inner(): pass return inner v = func()
-
特殊
- 默认没返回就是None
- return 1,2,3 等价于return(1,2,3)
-
-
执行函数
-
函数不被调用,内部代码永远不执行
def func(): return i func_list = [] for i in range(10): func_list.append(func) print(i) # 9 v1 = func_list[4]() v2 = func_list[0]()
func_list = [] for i in range(10): #func_list.append(lamdba:x) #函数不被调用,内部永远不执行 func_list.append(lamdba:i) #函数不被调用,内部永远不执行 print(func_list) #10个lambda函数 result = func_list[2]() print(result) #9
-
-
执行函数时,会新创建一块内存保存自己函数执行的信息 =》闭包
def base(arg): return arg def func(arg): def inner(): return arg return inner base_list = [] func_list = [] for i in range(10): base_list.append(base) func_list.append(func(i)) # 1. base_list 和func_list中分别保存了什么? """ base_list = [base,base,base......]共10个相同的base函数(内存地址) func_list = [inner,inner,inner......]共10个不同的inner(内存地址),从第一个i = 0,i = 1.....循环到9的不同inner函数的内存地址 """ # 2. 如果循环打印什么? for item in base_list: v = item() #执行base函数 print(v) #都是9 for data in func_list: v = data() print(v) #0,1,2,3,...9
总结:
- 传参:位置函数 > 关键字参数
- 函数不被调用,内部代码永远不执行
- 每次调用函数时,都会为此次调用开辟一块内存,内存可以保存自己以后想要用的值。
- 函数是作用域,如果自己作用域中没有,则往上级作用域找。
2.内置和匿名函数
- 内置函数
- 匿名函数
3.模块
- getpass
- random
- hashlib
4.重点作业
#1.看代码分析结果
func_list = []
for i in range(10):
func_list.append(lambda x:x + i)#此时列表中增加了i=0-9的匿名函数
for i in range(0,len(func_list)):#i=0-9
result = func_list[i](i)#重新覆盖列表中原i的值,i重新赋值并做参数传入函数
print(result)#结果为0,2,4,6....18
#2.看代码分析结果【面试题】
def f1():
print("f1")
return f3()
def f2():
print("f2")
return f1
def f3():
print("f3")
func = f2() #先算等号右边,f2函数执行,输出"f2"返回值为函数f1,此时 func = f1
result = func() #等号右边为f1(),函数执行后,输出"f1",返回值
print(result)
#3.分析代码(闭包和调用)
def func(name):
return lambda x: x + name
v1 = func(1) #形成闭包(lambda x:x+1)
v2 = func(2) #形成闭包(lambda x:x+2)
result1 = v1(100) #执行闭包函数,x = 100,return返回值为101
result2 = v2(200) #执行闭包函数,x = 200,return返回值为202
print(result1,result2)
内容详细
1.装饰器
#######################
def func(arg):
def inner():
arg()
return inner
def f1():
print(123)
v1 = func(f1)
v1()
#######################
def func(arg):
def inner():
arg()
return inner
def f1():
print(123)
return 666
v1 = func(f1) #{arg = f1,v1 = inner,函数inner的闭包}
result = v1() #v1() = inner(),arg = f1,执行inner()函数,结果为print(123),返回值为None
print(result) #结果为123,None
#######################
def func(arg):
def inner():
return arg() #后续执行函数arg()时,返回值返回给inner函数
return inner
def f1():
print(123)
return 666
v1 = func(f1) #{arg = f1,v1 = inner,函数inner的闭包}
result = v1() #v1() = inner(),arg = f1,执行inner()函数,结果为print(123),返回值为666
print(result) #结果为123,666
#######################
def func(arg):
def inner():
return arg()
return inner
def index():
print('123')
return 666
#示例一:
v1 = index() #执行index函数,打印'123',并返回666给v1
#示例二:
v2 = func(index) #index函数作为参数传入func()函数中执行,返回{arg=index函数}的inner函数闭包赋值给v2
index = 666 #index函数重新指向666内存地址,但是v2闭包中的index还是指向原来的index函数
v3 = v2()#因v2中有闭包,相当于执行函数index()并返回值传给inner函数,inner函数中return接收后赋值给v3。
print(v3)#所以结果为打印123,666
#示例三:
v4 = func(index)
index = v4
index()
通过以上的例子,得出装饰器最终的状态:
#第一形态
def func(arg):
print("此为index的装饰器")
def inner():
print("before")
v = arg()
print("after")
return v
return inner
def index():
print('123')
return 666
index = func(index)
index()
##最终形态:注意 @装饰器函数
def func(arg):
print("此为index的装饰器")
def inner():
print("before")
v = arg()
print("after")
return v
return inner
#第一步:执行func函数并将index函数作为参数传递,相当于func(index)
#第二步:将func的返回值重新赋值给下面的函数名。index = func(index)
@func
def index():
print('123')
return 666
print(index())
装饰器:在不改变原函数内部代码的基础上,在函数执行之前和执行之后自动执行某个功能
应用:
import time
def func():
time.sleep(4)
print(123)
start_time = time.time()#获取当前时间
func()
end_time = time.time()
time = start_time - end_time
print(time)
总结:
-
目的:在不改变原来函数的基础上,再函数执行前后在定义功能
-
编写装饰器的标准格式:
#装饰器的编写: def x(arg): def y(): ret = arg() return ret return y #装饰器的应用: @x def index(): pass @x def manager(): pass #执行函数,自动触发装饰器 v = index() m = manager() print(v,m)
应用场景:
- 想要为函数扩展功能时,可以选择用装饰器。
总结:
-
装饰器的编写格式
- 装饰器第一层函数return的返回值不加内层函数的括号
def 外层函数(参数): def 内层函数(*args,**kwargs): return 参数(*args,**kwargs) return 内层函数
-
装饰器应用格式:
@外层函数 def index(): pass index()
-
问题:为什么要加*args,**kwargs
2.推导式
列表推导式(常用,熟记)
-
基本格式
''' 目的:方便的生成一个列表 格式: v1 = [ i for i in 可迭代对象 ] v2 = [ i for i in 可迭代对象 if 条件 ] #条件为True,才可进行append ''' v1 = [i for i in 'alec'] v2 = [i+100 for i in range(10)] v3 = [99 if i>5 else 66 for i in range(10)] def func(): return 100 v4 = [func for i in range(10)] v5 = [ lambda : 100 for i in range(10) ] result = v5[9]() def func(): return i v6 = [func for i in range(10)] result = v6[5]() v7 = [lambda : i for i in range(10)] result = v7[5]() #新浪微博面试题 #############第一题################ val = [lambda x:x*i for i in range(10)] #1.请问val是什么结果? #2.请问val[0](2)的结果是什么? #############第二题################ def num(): return [lambda x:i*x for i in range(4)] #num() -> [函数,函数,函数,函数] print ([m(2) for m in num()])#[6,6,6,6] #1.看代码分析结果 #############筛 选################ v8 = [i for i in rang(10) if i>5 ] #第一步:计算for i in range(10) #第二步:判断条件if i>5 #第三步:符合判断条件的依次赋值给i,添加进列表
集合推导式(集合特性:去重)
- 跟列表推导式雷同
- 仅适用集合的特性
v1 = {i for i in 'alec'}
字典推导式
- 跟列表推导式雷同
- 仅适用于字典的特性
- key键不可重复
v1 = { 'k'+str(i):i for i in range(10) }
总结
-
装饰器(特重点,理解+巩固)
-
编写格式:双层嵌套函数
-
应用格式:@外层函数
-
重点记住:
@xx # index = xx(index) def index(): pass index() #为加入装饰器的index
-
-
推导式(常用优化)
-
模块
import time v = time.time() #获取当前时间 time.sleep(2) #时间睡眠2秒