装饰器

函数对修改封闭,对扩展开放
例子:
1.对函数的执行时间进行检测
import time
def foo():
start = time.time()
print('foo....')
time.sleep(2)
end = time.time()
print('spend %s' % (end - start))
def test():
start = time.time()
print('test....')
time.sleep(2)
end = time.time()
print('spend %s' % (end - start))
foo()
test()
问题:一旦修改,所有函数都会改变,并且对更多的函数进行同样操作的话,就会使代码出现大量的重复

2.改进方法,定义show_time函数
def foo():
print('foo....')
time.sleep(2)

def show_time(f):
start = time.time()
f()
end = time.time()
print('spend %s' % (end - start))
show_time(foo)
问题:该方法改变了原生函数的调用方式

3.引入装饰器,装饰器就是为之前的函数添加新的功能
def foo():
print('foo....')
time.sleep(2)

def test():
print('test....')
time.sleep(2)

def show_time(f):
def inner():
start = time.time()
f()
end = time.time()
print('spend %s' % (end - start))
return inner

foo = show_time(foo)
foo()
test = show_time(test)
test()

4.python的优雅写法
def show_time(f):
def inner():
start = time.time()
f()
end = time.time()
print('spend %s' % (end - start))
return inner

@show_time # test = show_time(test)
def test():
print('test....')
time.sleep(2)
test() #test执行部分从test到了show_time

5.再次优化
def show_time(f):
def inner(*x, **y):
start = time.time()
f(*x, **y)
end = time.time()
print('spend %s' % (end - start))
return inner

@show_time
def add(*a, **b):
print(sum(a),sum(b[i] for i in b))
time.sleep(1)
add(1, 2, 5, 6, x=5, y=8)

6.装饰器加参数,直接加入无法传参
def logger(flag=''):
def show_time(f):
def inner(*x, **y):
start = time.time()
f(*x, **y)
end = time.time()
print('spend %s' % (end - start))
if flag=='true':
print('日志记录')
return inner
return show_time

@logger('true') # @show_time
def add(*a, **b):
print(sum(a),sum(b[i] for i in b))
time.sleep(1)
add(1, 2, 5, 6, x=5, y=8)

装饰器注意无参数情况下必须两层,即show_time下必须存在inner,有参数情况下要有三层

实战运用:编写一个网页登陆
# 实现
# 1.提示用户选择页面
# 2.检测是否登陆,没有登陆时需要登陆,登陆则进入页面
# 3.登陆模式可以选择

# 自定义一个用户 'lql', '123456'
user, passwd = 'lql', '123456'
login_status = False

# 登陆装饰器,判断是否登陆,判断登陆方式
def login_type(auth_type='jindong'):
def login(f):
def test():
global login_status
if not login_status:
if auth_type == 'jindong':
username = input('username:')
password = input('password:')
if user == username and passwd == password:
print('welcome...')
f()
login_status = True
elif auth_type == 'weixin':
username = input('weixinusername:')
password = input('weixinpassword:')
if user == username and passwd == password:
print('welcome...')
f()
login_status = True
else:
f()
return test
return login

# 页面的调用
@login_type(auth_type='jindong')
def home():
print('welcome to home page')

@login_type(auth_type='weixin')
def finance():
print('welcome to finance page')

@login_type()
def book():
print('welcome to book page')

# 生成一个存储页面的列表
page = ['home', 'finance', 'login']
for i in range(3):
print(i+1,page[i])

page_name = None

# 实现选择页面
while page_name != 'q':
page_name = input('>>')
if page_name == '1':
home()
elif page_name == '2':
finance()
elif page_name == '3':
book()





posted on 2018-05-25 10:30  风度翩翩的机器空  阅读(294)  评论(0编辑  收藏  举报

导航