装饰器练习
# -*- coding=utf-8 -*- # !/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2020/5/15 23:46 # @Author : "小多肉" # @Email : 1021181701@qq.com """ TODO: 1、实现一个网络请求超时重试的装饰器,装饰下面的功能函数 如果请求网络超时,或者连接超时,可以重新发送请求,如果重试三次之后,还是超时,抛出对应的异常 def request_http(url): import requests return requests.get(url, timeout=5) 2、请设计一个装饰器,接收一个int类型的参数number,可以用来装饰任何的函数, 如果函数运行的时间大于number,则打印出函数名和函数的运行时间 (面试真题) 3、 请设计一个装饰器 ,可以给函数扩展登录认证的功能(提示数账号密码,然后进行校验), 多个函数同时使用这个装饰器, 调用函数的时候,只要登录成功一次, 后续的函数无需再进行登录(默认的认证账号:qwe123,密码:123456) (面试真题) """ # ###########################第一题################################## def retry(fun): def wrapper(*args, **kwargs): for i in range(4): try: res = fun(*args, **kwargs) except Exception as e: if i == 0: print(f"第一次请求失败!!!{e}\n正在尝试为您重新发起请求。") else: print(f"第{i}次重试……") if i == 3: raise e continue else: print("请求成功!!!", res) break return wrapper @retry def request_http(url): import requests return requests.get(url, timeout=5) # request_http("http://www.google.com.hk") print("---------------------第一题-------------------------") request_http("https://www.python.org/doc/") print("---------------------第一题异常情况-------------------------") try: request_http("http://www.google.com.hk") except Exception: print("重试三次都失败了,抛出异常。") # ############################第二题################################# """ 2、请设计一个装饰器,接收一个int类型的参数number,可以用来装饰任何的函数, 如果函数运行的时间大于number,则打印出函数名和函数的运行时间 (面试真题) """ import time def performance(number): def decorator(fun): def wrapper(*args, **kwargs): start_time = time.time() print("-------start--------", start_time) fun(*args, **kwargs) end_time = time.time() print("-------end--------", end_time) dur_time = end_time - start_time if dur_time > number: print(f"{fun.__name__}函数的运行时间为:{dur_time}") return wrapper return decorator @performance(0.1) def request_http2(url): import requests return requests.get(url) print("-------------------第二题---------------------------") request_http2("http://www.google.cn/") # ############################第三题################################# """ 3、 请设计一个装饰器 ,可以给函数扩展登录认证的功能(提示数账号密码,然后进行校验), 多个函数同时使用这个装饰器, 调用函数的时候,只要登录成功一次, 后续的函数无需再进行登录(默认的认证账号:qwe123,密码:123456)(面试真题) """ LOGIN_FLAG = 0 def login_check(func): def wrapper(*args, **kwargs): global LOGIN_FLAG if func.__name__ == "login": func() elif LOGIN_FLAG: func(*args, **kwargs) else: print("检测到您未成功登录,请先登录。") return wrapper @login_check def login(): account = input("请输入账号:") password = input("请输入密码:") if account == "qwe123" and password == "123456": global LOGIN_FLAG LOGIN_FLAG = 1 else: print("用户名或密码错误!登录失败!!!") @login_check def func1(): print("函数1") @login_check def func2(): print("函数2") @login_check def func3(): print("函数3") print("------------第三题-----------") func1() login() func2() func3()