1、编写函数,(函数执行的时间用time.sleep(n)模拟)
import time def test(): print('hello,boy!') time.sleep(3) def calculate(func): time_start = time.time() func() time_stop = time.time() print('{}'.format(time_stop - time_start)) calculate(test)
hello,boy!
3.0033867359161377
2、编写装饰器,为函数加上统计时间的功能
import time def timmer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print('执行时间为:{}'.format(stop_time - start_time)) return res return wrapper @timmer def information(ip, port): message = '服务IP:{},端口号:{}'.format(ip, port) time.sleep(3) return message res = information('192.168.80.127', port=9090) print(res)
效果:
执行时间为:3.003328323364258
服务IP:192.168.80.127,端口号:9090
3、编写装饰器,为函数加上认证的功能
from functools import wraps from prettytable import PrettyTable import os local_user = None userfile = os.path.dirname(os.path.abspath(__file__)) + '/db.txt' def check_login(func): @wraps(func) def wrapper(*args, **kwargs): if local_user: res = func(*args, **kwargs) else: print('请先登录,在执行{}功能!'.format(func.__name__)) res = None return res return wrapper def login(): global local_user user_dict = {} flag = True with open(userfile, mode='rb') as f: for line in f: name, passwd = line.decode('utf-8').strip(' ').split(':') user_dict[name] = passwd while flag: user_name = input('请输入你的用户名:').strip() if user_name in user_dict: user_passwd = input('请输入你的密码:').strip() if user_passwd == user_dict.get(user_name): print('登录成功!') local_user = user_name break else: print('密码错误,登录失败!') else: print('账号不存在!') _continue = input('是否继续登录账号(y,n):').strip() flag = False if _continue.lower() == 'n' else True @check_login def ip_info(ip='192.168.80.128', port=8080): print('call from:{}'.format(ip)) message = '服务地址:{},访问端口号:{}'.format(ip, port) return message user_choice = { '0':(None,'退出'), '1':(login,'登录'), '2':(ip_info,'查看服务器信息') } def main(): flag = True tb = PrettyTable(field_names=['功能编号','功能名称']) for k in user_choice: tb.add_row([k,user_choice[k][1]]) while flag: print(tb) choice = input('请选择功能编号:').strip() if choice == '0': break elif choice in user_choice: user_choice[choice][0]() if __name__ == '__main__': main()
实现效果:
+----------+----------------+ | 功能编号 | 功能名称 | +----------+----------------+ | 0 | 退出 | | 1 | 登录 | | 2 | 查看服务器信息 | +----------+----------------+ 请选择功能编号:2 2 请先登录,在执行ip_info功能! +----------+----------------+ | 功能编号 | 功能名称 | +----------+----------------+ | 0 | 退出 | | 1 | 登录 | | 2 | 查看服务器信息 | +----------+----------------+ 请选择功能编号:1 1 请输入你的用户名:egon egon 请输入你的密码:vip666 vip666 登录成功! +----------+----------------+ | 功能编号 | 功能名称 | +----------+----------------+ | 0 | 退出 | | 1 | 登录 | | 2 | 查看服务器信息 | +----------+----------------+ 请选择功能编号:2 2 call from:192.168.80.128 +----------+----------------+ | 功能编号 | 功能名称 | +----------+----------------+ | 0 | 退出 | | 1 | 登录 | | 2 | 查看服务器信息 | +----------+----------------+ 请选择功能编号:
4、编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码
注意:从文件中读出字符串形式的字典,可以用eval('{"name":"egon","password":"123"}')转成字典格式
#!/usr/bin/env python # -*- coding:utf-8 -*- import os from functools import wraps from prettytable import PrettyTable userfile = os.path.dirname(os.path.abspath(__file__)) + '/db.txt' local_user = None def login(): with open(userfile,mode='r',encoding='utf-8') as f: user_dict = eval(f.read().strip(' ')) global local_user flag = True while flag: login_name = input('请输入登录名:').strip() if login_name == user_dict['name']: login_passwd = input('请输入登录密码:').strip() if login_passwd == user_dict['password']: print('用户{}登录成功!'.format(login_name)) local_user = login_name break else: print('密码错误,登录失败!') else: print('用户{}不存在,请先注册!'.format(login_name)) _continue = input('是否继续登录(y,n):').strip() flag = False if _continue.lower() == 'n' else True def check_login_status(func): @wraps(func) def wrapper(*args, **kwargs): if local_user is None: print('请先登录,才能执行使用{}功能'.format(func.__name__)) res = None else: res = func(*args, **kwargs) return res return wrapper @check_login_status def student(name='姜春', age=18, gender='male'): print('姓名:{} 年龄:{} 性别:{}'.format(name, age, gender)) return name @check_login_status def play(do='learn', address='shanghai', date='3-23'): print('项目:{} 地址:{} 日期:{}'.format(do, address, date)) return do user_choice = { '0': (None, '退出'), '1': (login, '登录'), '2': (student, '查看学生'), '3': (play, '玩') } def main(): flag = True tb = PrettyTable(field_names=['功能编号', '功能名称']) for k in user_choice: tb.add_row([k, user_choice[k][1]]) while flag: print(tb) choice = input('请输入功能编号:').strip() if choice.isdigit(): if choice == '0': break elif choice in user_choice: user_choice[choice][0]() if __name__ == '__main__': main()
5、编写装饰器,为多个函数加上认证功能,要求登录成功一次,在超时时间内无需重复登录,超过了超时时间,则必须重新登录
import os, time from functools import wraps from prettytable import PrettyTable userfile = os.path.dirname(os.path.abspath(__file__)) + '/db.txt' local_user = None local_time = None def login(): with open(userfile, mode='r', encoding='utf-8') as f: user_dict = eval(f.read().strip(' ')) global local_user,local_time flag = True while flag: login_name = input('请输入登录名:').strip() if login_name == user_dict['name']: login_passwd = input('请输入登录密码:').strip() if login_passwd == user_dict['password']: print('用户{}登录成功!'.format(login_name)) local_user = login_name local_time = int(time.time()) break else: print('密码错误,登录失败!') else: print('用户{}不存在,请先注册!'.format(login_name)) _continue = input('是否继续登录(y,n):').strip() flag = False if _continue.lower() == 'n' else True def check_login_status(func): @wraps(func) def wrapper(*args, **kwargs): global local_user,local_time if local_user is None: print('请先登录,才能执行使用{}功能'.format(func.__name__)) res = None else: if int(time.time())-300 == local_time: local_user = None local_time = None res = None else: res = func(*args, **kwargs) return res return wrapper @check_login_status def student(name='姜春', age=18, gender='male'): print('姓名:{} 年龄:{} 性别:{}'.format(name, age, gender)) return name @check_login_status def play(do='learn', address='shanghai', date='3-23'): print('项目:{} 地址:{} 日期:{}'.format(do, address, date)) return do user_choice = { '0': (None, '退出'), '1': (login, '登录'), '2': (student, '查看学生'), '3': (play, '玩') } def main(): flag = True tb = PrettyTable(field_names=['功能编号', '功能名称']) for k in user_choice: tb.add_row([k, user_choice[k][1]]) while flag: print(tb) choice = input('请输入功能编号:').strip() if choice.isdigit(): if choice == '0': break elif choice in user_choice: user_choice[choice][0]() if __name__ == '__main__': main()
6、选做题
# 思考题(选做),叠加多个装饰器,加载顺序与运行顺序,可以将上述实现的装饰器叠加起来自己验证一下 # @deco1 # index=deco1(deco2.wrapper的内存地址) # @deco2 # deco2.wrapper的内存地址=deco2(deco3.wrapper的内存地址) # @deco3 # deco3.wrapper的内存地址=deco3(index) # def index(): # pass