码迷,mamicode.com
首页 > 编程语言 > 详细

Python基础-----装饰器

时间:2018-10-04 10:24:26      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:lis   索引   fun   utf-8   imm   用户   python   记录   star   

#!/usr/bin/env python
# -*- coding:utf-8 -*-

一、装饰器定义
器即函数;装饰即修饰,意指为其他函数添加新功能;
装饰器定义:本质就是函数,功能是为其他函数添加新功能
二、装饰器的原则
1.不修改被装饰函数的源代码(开放封闭原则)
2.为被装饰函数添加新功能后,不修改被修饰函数的调用方式
三、高阶函数
满足如下条件之一就可称之为高阶函数
1.函数接收的参数是一个函数名
2.函数的返回值是一个函数名
高阶函数总结
1.函数接收的参数是一个函数名
  作用:在不修改函数源代码的前提下,为函数添加新功能,
  不足:会改变函数的调用方式
2.函数的返回值是一个函数名
  作用:不修改函数的调用方式
  不足:不能添加新功能
四、闭包
闭包:在一个作用域里放入定义变量(或嵌套函数),相当于打了一个包
想要给内部传入参数,用闭包的话只需要在最外部传入即可
def father(name):
def son():
def grandson():
print(‘from %s‘%name)
grandson()
son()

father(‘林海峰‘)
五、装饰器框架实现
‘‘‘
import time
def timmer(func): #func = test
def wrapper():
start_time = time.time()
func() #执行test函数
stop_time = time.time()
print(‘运行时间%s‘%(stop_time - start_time))
return wrapper

def test():
time.sleep(3)
print(‘函数运行完毕‘)

test = timmer(test) #返回的是wrapper的函数地址
test() #执行wrapper函数,内部再运行test函数
‘‘‘
上面代码符合装饰器的基本原则,但是调用test函数之前进行了赋值操作
六、装饰器语法糖
@装饰函数 (将该句代码放置于修饰函数前即可)
就上例来讲,@timmer 就相当于 test = timmer(test)
‘‘‘
import time
def timmer(func): #func = test
def wrapper():
start_time = time.time()
func() #执行test函数
stop_time = time.time()
print(‘运行时间%s‘%(stop_time - start_time))
return wrapper

@timmer #等同于test = timmer(test)
def test():
time.sleep(3)
print(‘函数运行完毕‘)

test()
‘‘‘
# 七、加上返回值
‘‘‘
import time
def timmer(func): #func = test
def wrapper():
start_time = time.time()
res = func() #执行test函数
stop_time = time.time()
print(‘运行时间%s‘%(stop_time - start_time))
return res
return wrapper

@timmer #等同于test = timmer(test)
def test():
time.sleep(3)
print(‘函数运行完毕‘)
return ‘这是test的返回值‘
a = test() #实际执行wrapper函数
print(a)
‘‘‘
八、加上参数
‘‘‘import time
def timmer(func): #func = test
def wrapper(name,age):
start_time = time.time()
res = func(name,age) #执行test函数,参数来自wrapper接收的参数
stop_time = time.time()
print(‘运行时间%s‘%(stop_time - start_time))
return res
return wrapper

@timmer #等同于test = timmer(test)
def test(name,age):
time.sleep(3)
print(‘我叫%s,年龄%d‘%(name,age))
return ‘这是test的返回值‘
a = test(‘alex‘,18) #实际执行wrapper函数‘‘‘
但是参数是固定的,不适用于所有函数,则改变如下:
‘‘‘import time
def timmer(func): #func = test
def wrapper(*args,**kwargs): #可以用* **来传入多参数
start_time = time.time()
res = func(*args,**kwargs) #执行test函数,参数来自wrapper接收的参数
stop_time = time.time()
print(‘运行时间%s‘%(stop_time - start_time))
return res
return wrapper

@timmer #等同于test = timmer(test)
def test(name,age):
time.sleep(3)
print(‘我叫%s,年龄%d‘%(name,age))
return ‘这是test的返回值‘

@timmer
def test1(name,age,gender):
time.sleep(3)
print(‘我叫%s,年龄%d,性别%s‘%(name,age,gender))
return ‘这是test的返回值‘
a = test(‘alex‘,18) #实际执行wrapper函数
b = test1(‘tony‘,22,‘male‘) #该处将‘tony‘,22,‘male‘参数放入*args == *(‘tony‘,22,‘male‘)(一一对应,相当于解压)‘‘‘
九、列表解压
如要获取列表的第一个和最后一个值,不用索引来取
‘‘‘l = [10,2,3,4,5,7,5,4,2,32]
first_num,*other_num,last_num = l # *+变量名 表示中间的所有元素
print(first_num,last_num)
print(*other_num)‘‘‘

如需互换两个变量的值
‘‘‘a = 1
b = 2
a,b = b,a
print(a,b)‘‘‘

十、实例(验证功能装饰器)
user_list = [
{‘name‘:‘a‘,‘password‘:‘123‘},
{‘name‘:‘b‘,‘password‘:‘123‘},
{‘name‘:‘c‘,‘password‘:‘123‘},
{‘name‘:‘d‘,‘password‘:‘123‘}
] #所有用户信息列表(值为字符串类型)

current_user = {‘username‘:None,‘login‘:False} #记录用户当前登录状态

def auth_func(func):
def wrapper(*args,**kwargs):
if current_user[‘username‘] and current_user[‘login‘]: #如果已经登录,则无需登陆
res = func(*args,**kwargs)
return res
username = input(‘用户名:‘).strip() #上面if不成立,则登录
password = input(‘密码:‘).strip()
for user_dic in user_list: #for遍历的是用户列表的中用户信息字典
if username == user_dic[‘name‘] and password == user_dic[‘password‘]: #登录验证
current_user[‘username‘] = username #登录成功,更改用户状态
current_user[‘login‘] = True
res = func(*args,**kwargs)
return res
else: #该处else没放在if下是因为,要遍历所有的用户列表才能判断是否真的有错
print(‘用户名或密码错误,请重新登录!‘)
return wrapper

@auth_func
def home(name):
print(‘欢迎 %s 来到主页‘%name)

@auth_func
def shopping_car(name):
print(‘%s 的购物车里有:学习用品,生活用品!‘%name)

home(‘Jerry‘)
print(current_user)
shopping_car(‘Jerry‘)

Python基础-----装饰器

标签:lis   索引   fun   utf-8   imm   用户   python   记录   star   

原文地址:https://www.cnblogs.com/Meanwey/p/9741285.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!