python day14

装饰器简易版本

# 给函数添加统计执行时间的功能

def outer(func):  # func指向的是函数名index
   # func = index
   def get_time():
       start_time = time.time()
       func()
       end_time = time.time()
       print('函数运行时间:%s' % (end_time - start_time))
   return get_time  # 将get_time函数名返回出去
index = outer(index)  # outer(index函数名)
# 左侧的变量名index指代是函数名get_time
index()

解决参数问题

import time
def index():
   time.sleep(3)
   print('亚洲最大的线上赌场开业了 双眼发红光的在线发牌!!!')
def login(name):
   time.sleep(1)
   print('%s正在发牌'%name)
def outer(func):  # func指向的是函数名login
   # func = login
   def get_time(*args,**kwargs):
       start_time = time.time()
       func(*args,**kwargs)
       end_time = time.time()
       print('函数运行时间:%s' % (end_time - start_time))
   return get_time  # 将get_time函数名返回出去
login = outer(login)
login('jason')
index = outer(index)
index()

解决返回值问题

import time
def index():
   time.sleep(3)
   print('亚洲最大的线上赌场开业了 双眼发红光的在线发牌!!!')
   return 'from index'
def login(name):
   time.sleep(1)
   print('%s正在发牌'%name)
   return 'from login'
def outer(func):  # func指向的是函数名login
   # func = login
   def get_time(*args,**kwargs):
       start_time = time.time()
       res = func(*args,**kwargs)  # 接收被装饰函数的返回值
       end_time = time.time()
       print('函数运行时间:%s' % (end_time - start_time))
       return res  # 执行完get_time之后返回被装饰函数执行之后的返回值
   return get_time  # 将get_time函数名返回出去
# index = outer(index)
# res = index()
# print(res)
login = outer(login)
res1 = login('jason')
print(res1)

认证装饰器

# 今天只需要掌握简单版本(每个都校验用户名和密码)
# 记录用户状态的版本多花时间去练
import time
def index():
   time.sleep(1)
   print('百万大奖等你来拿 赶快加入我们吧!!!')
def home():
   time.sleep(1)
   print('学学学 一天到晚就是学 卷死你们这些家伙')
def register():
   time.sleep(1)
   print('注册功能')
# 给index函数添加认证功能
"""
在调用index之前需要用户输入用户名和密码
  正确才可以调用
  错误直接拒绝
"""
# 定义一个用于记录用户是否登录的数据
is_login = {'is_login':False}


def login_auth(func):
   def auth(*args,**kwargs):
       # 1.1 先判断用户是否已经登录
       if is_login.get('is_login'):
           # 3.正常执行函数index
           res = func(*args, **kwargs)
           return res
       # 1.先获取用户的用户名和密码
       username = input('username>>>:').strip()
       password = input('password>>>:').strip()
       # 2.校验用户名和密码是否正确
       if username == 'jason' and password == '123':
           # 3.正常执行函数index
           res = func(*args,**kwargs)
           # 4.将记录用户登录状态的数据修改
           is_login['is_login'] = True
           return res
       else:
           print('用户名或密码错误 无法执行函数')
   return auth
index = login_auth(index)
index()
home = login_auth(home)
home()
register = login_auth(register)
register()

装饰器固定模板

def outer(func):
   def inner(*args, **kwargs):
       print('执行函数之前可以添加的额外功能')
       res = func(*args, **kwargs)  # 执行被装饰的函数
       print('执行函数之后可以添加的额外功能')
       return res  # 将被装饰函数执行之后的返回值返回
   return inner

装饰器语法糖

def outer(func):
   def inner(*args, **kwargs):
       print('执行函数之前可以添加的额外功能')
       res = func(*args, **kwargs)  # 执行被装饰的函数
       print('执行函数之后可以添加的额外功能')
       return res  # 将被装饰函数执行之后的返回值返回
   return inner
@outer  # index = outer(index)
def index(*args, **kwargs):
   print('from index')
@outer  # home = outer(home)
def home():
   print('from home')
"""
装饰器语法糖是写规范
  语法糖必须紧贴在被装饰对象的上方
装饰器语法糖内部原理
  会自动将下面紧贴着的被装饰对象名字当做参数传给装饰器函数调用
"""

双层语法糖

# 统计函数运行时间
import time
def get_time(func):
   def inner(*args, **kwargs):
       start_time = time.time()
       res = func(*args, **kwargs)  # 执行被装饰的函数
       end_time = time.time()
       print('函数执行时间:%s'%(end_time-start_time))
       return res  # 将被装饰函数执行之后的返回值返回
   return inner
# 校验用户登录装饰
def login_auth(func):
   def inner(*args, **kwargs):
       # 1.先获取用户的用户名和密码
       username = input('username>>>:').strip()
       password = input('password>>>:').strip()
       # 2.校验用户名和密码是否正确
       if username == 'jason' and password == '123':
           res = func(*args, **kwargs)  # 执行被装饰的函数
           return res  # 将被装饰函数执行之后的返回值返回
       print('用户名或密码错误 无权限执行')
   return inner
@login_auth
@get_time
def index():
   time.sleep(1)
   print('from index')
index()

装饰器修复技术

from functools import wraps
def outer(func):
   @wraps(func)  # 修复技术就是为了让被装饰对象更加不容易被察觉装饰了
   def inner(*args, **kwargs):
       print('执行函数之前可以添加的额外功能')
       res = func(*args, **kwargs)  # 执行被装饰的函数
       print('执行函数之后可以添加的额外功能')
       return res  # 将被装饰函数执行之后的返回值返回
   return inner


@outer  # index = outer(index)
def index():
   print('from index')
print(index)
help(index)

def home():
   """这是一个home函数"""
   print('from home')
# help(index)
# help(home)
# print(index)
# help(len)

练习题

# 判断七句print执行顺序
def outter1(func1):
   print('加载了outter1')
   def wrapper1(*args, **kwargs):
       print('执行了wrapper1')
       res1 = func1(*args, **kwargs)
       return res1
   return wrapper1

def outter2(func2):
   print('加载了outter2')
   def wrapper2(*args, **kwargs):
       print('执行了wrapper2')
       res2 = func2(*args, **kwargs)
       return res2
   return wrapper2

def outter3(func3):
   print('加载了outter3')
   def wrapper3(*args, **kwargs):
       print('执行了wrapper3')
       res3 = func3(*args, **kwargs)
       return res3
   return wrapper3


@outter1
@outter2
@outter3
def index():
   print('from index')

有参装饰器

def outer(source_data):
   # source_data = 'file'
   def login_auth(func):
       def auth(*args,**kwargs):
           # 2.校验用户名和密码是否正确
           # 数据的校验方式可以切换多种
           if source_data == 'file':
               # 从文件中获取用户数据并比对
               print('file文件获取')
           elif source_data == 'MySQL':
               # 从MySQL数据库中获取数据比对
               print('MySQL数据库获取')
           elif source_data == 'postgreSQL':
               # 从postgreSQL数据库中获取数据对比
               print('postgreSQL数据库获取')
           else:
               print('用户名或密码错误 无法执行函数')
       return auth
   return login_auth

@outer('file')
def index():
   print('from index')
@outer('MySQL')
def home():
   print('from home')

index()
home()
posted @ 2021-11-17 19:34  杰尼龟无所畏惧  阅读(67)  评论(0)    收藏  举报