python装饰器 | 装饰器语法糖 | 有参装饰器

装饰器

装饰器简介

'''
装饰器:由名称空间 函数对象 闭包函数组合而来
'''

器:指的是工具
装饰:给被装饰对象添加额外的功能

装饰器的原则:
	开放封闭原则 
    	开放:对扩展开放
        封闭:对修改封闭
        
装饰器核心思想:
 	在不改变被'装饰对象内部代码' 和 '原有调用方式' 的基础之上添加额外功能
    
def index():
    print('from index')
index()

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


import time

# print(time.time())  # 1637036293.0609405
# 获取的结果叫时间戳(运行代码的那一刻距离1970-1-1所经历的秒数)
# time.sleep(3)  # 让程序原地等待3秒
# print('睡三秒运行')


def index():
    time.sleep(3)
    print('from index')
# 统计index函数的执行时间
# 在函数运行之前统计一次时间
start_time = time.time()
index()
# 在函数运行完毕之后再次统计
end_time = time.time()
# 计算差值
print(end_time - start_time)

装饰器简易版本

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

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(2)
    print('%s正在发牌'%name)
def outer(func) # func指向的是函数名login
	#func = login
    def get_time(*args,**kwargs):
        start_time = time.time()
        func()
        end_time = time.time()
        print('执行时间为%s'%(end_time - start_time))
    return get_time  # 将get_time函数名返回出去
login = outer(login)
login('jjjjj')
index = outer(index)
index()

解决返回值问题

import time
def index():
    time.sleep(3)
    print('第一次代码')
    return 'from index'
def login(name):
    time.sleep(2)
    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函数名返回出去
login = outer(login)
res = login('jjjjj')
print(res)    
index = outer(index)
index()

认证装饰器

# 可以达到记录用户状态的效果  
import time
def index():
    time.sleep(2)
    print('学习学习学习')
def home():
    time.sleep(2)
    print('还是学习')
def register():
    time.sleep(2)
    print('注册功能')
# 要求: 给index函数添加认证功能
'''
在调用index之前需要用户输入用户名和密码
	正确才可以使用 
	错误直接拒绝

'''
# 定义一个用于记录用户是否登录的数据
is_login = {'is_login':Flase}

def login_auth(func):
    def auth(*args,**kwargs):
        # 先判断用户是否登录
        if is_login.get('is_login'):
            res = func(*args,**kwargs)
            return res
        # 先获取用户的用户名和密码
		username = input('username>>>>').strip()
        psw = input('psw>>>>').strip()
        # 校验用户名和密码是否正确
        if username == 'jason' and psw == '123':
           	res = func(*args,**kwargs)
            # 将记录用户登录状态的数据修改
            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(): 
    print('sssss')
index()  

'''
装饰器语法糖其实就是书写规范
	语法糖必须紧贴在被装饰函数对象的上方
装饰器语法糖内部原理
	会自动将紧贴着的被装饰函数对象的函数名当作参数传给装饰器调用
'''

双层语法糖

#  统计函数运行时间
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):
        username = input('username>>>').strip()
        psw = input('psw>>>>').strip()
       	if username == 'jason' and psw == '123':
            res = func(*args,**kwargs)
            return res
        print('用户名或密码错误')
    return inner
@login_auth
@get_time
def index():
    time.sleep(2)
    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


@outer1  # index = outer1(outer2函数的返回值(函数名))
@outer2  # outer2函数的返回值(函数名) = outer2(outer3函数的返回值(函数名))
@outer3  # outer3函数的返回值(函数名) = outer3(真正的index)
def index():
    print('from index')
index()

# 执行为:
加载了outter3
加载了outter2
加载了outter1
执行了wrapper1
执行了wrapper2
执行了wrapper3
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')    # 先执行函数在执行语法糖结构   则先执行outer('file')  在执行outer返回											值login_auth(index) 
def index():
    print('from index')
@outer('MySQL')
def home():
    print('from home')

index()
home()

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值