1. 装饰器
装饰器其实是一个函数,作用是装饰其他函数装饰器的特点:1. 不改变被装饰的函数的源代码的情况下添加函数的功能 2. 不改变被装饰的函数的调用方式装饰器的组成方式:高阶函数+嵌套函数
1.1 高阶函数
高阶函数,以一个函数名作为参数,传递给另一个函数,这个函数就是高阶函数。
print(abs(-10)) # abs,内置函数,返回一个数的绝对值 def test(num,func): # 高阶函数,以一个函数名作为参数,传递给另一个函数 absNum = func(num) # 调用函数 print(absNum) test(-2,abs) # 注意,这里写的是abs,是函数名,没有加()
map和lambda函数
map函数是一个内置的函数,它也是一个高阶函数,配合lambda(匿名函数),可以实现很多功能
lambda函数
lambda是匿名函数,没有函数名,最多支持三元运算,是一种简单的函数
三元运算:
a,b,c = 1,2,3 d = 5 if a>b else c # 如果条件成立,d=5,否则就 =c
lambda函数,以:分开,:左边写参数(可以多个,以‘,’分割),右边写函数体
a = lambda n:n*2 if n<10 else n print(a(6)) b = lambda x,y:x+y print(b(1,1)) ''' 上面的b,等同于: def b(x,y): return x+y '''
map函数
map函数是一个高阶函数; 语法:map(function, iterable, ...),对iterable对象的每个元素执行function,然后将结果放到map对象中
# 通过map lambda 对一个列表的每个元素求平方 num = [1,2,3,4,5] n = map(lambda x:x**2,num) print(list(n)) # 转换成list打印出来
1.2 嵌套函数
嵌套函数,顾名思义,函数内部嵌套了一层或多层函数
def test(): print('this is outer func') def test2(): # 嵌套的函数 print('this is inner func') test2() # 在test中调用内层函数 test()
1.3 装饰器
python的内存分配机制:1. 普通变量内存分配,例如:x=1 y=x 在这个例子中,x相当于一个门牌号,指向一个内存地址,内存里面放着1, 而y=x相当于这个内存加了一个门牌号:y ,它俩实际上指向一个内存地址, 当x,y都不再调用1时,这个内存才会被定期的内存刷新清理掉2. 函数的内存分配:例如 def get(): pass 这个例子中,函数名get是一个内存地址,内存里存的是函数的内容,在内存中只是作为字符串存放,这里就是pass, 所以print(get)得到的是一个内存地址,而get()才是真的执行了函数的内容下面给test1添加一个用来计时的装饰器:timer
1 import time 2 from time import sleep 3 4 def timer(func): # 高阶函数:以函数作为参数 5 def deco(*args,**kwargs): # 嵌套函数,在函数内部以 def 声明一个函数,接受 被装饰函数的所有参数 6 time1 = time.time() 7 func(*args,**kwargs) 8 time2 = time.time() 9 print('func elapsed %s' %(time2-time1)) 10 return deco # 注意,返回的函数没有加括号!所以返回的是一个内存地址,而不是函数的返回值 11 12 @timer # 装饰器,放在被装饰函数的顶部,等同于: test1 = timer(test1) = deco 13 def test1(name): 14 print('test1 is running, will sleep 1 seconds...') 15 sleep(1) 16 print('test1 is over.',name) 17 18 test1('wwwww')
上述代码执行步骤:
1. 执行第4行代码。创建变量timer,将timer的函数体存入内存
2. 执行12行代码。相当于test1 = timer(test1),此时调用了timer函数,将会执行第5行:创建变量deco:将deco的函数体存入内存;继续执行第10行代码,将返回值赋值给test1,此时test1就相当于deco
3. 执行18行代码。根据上述第2步,test1相当于deco,所以此时就相当于执行deco('wwwww')
4. 所以,执行第5行代码,开始执行deco('wwwww'),然后是第6行、第7行:在第7行时,func这个形参是第4行得来的,在上述第2步的时候,将test1传递给了timer,所以这里的func就是test1
5. 因此,执行test1(),所以代码执行第14-16行,然后继续回到第8行、第9行,完成函数deco()的执行。
1.4 带参数的装饰器
user,passwd = 'alex','123' def auth(log_type): print(log_type) def outwrapper(func): # 不带参数的装饰器应该从这里开始,带了参数相当于外面多了一层函数 def wrapper(*args,**kwargs): username = input('username:') password = input('password:') if username == user and password == passwd: res = func(*args,**kwargs) return res else: print('username or Password is wrong.') return wrapper return outwrapper ''' 正常的装饰器不带括号: @auth 等同于 index = auth(index) 而如果加了括号(此处带了一个关键字参数),则执行此装饰器(本质是函数),将被装饰函数作为参数传递给里层的函数 ''' @auth(log_type = 'local') # index = auth(log_type='local') = outwrapper(index) = wrapper def index(): print('welcome to index page.') return 1 index()