• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
武纪亨
博客园    首页    新随笔    联系   管理    订阅  订阅
python的装饰器

内容概要

  • 装饰器的概念(重点)
  • 装饰器简易版本
  • 装饰器进阶版本
  • 装饰器练习(认证功能)
  • 装饰器固定模板
  • 装饰器语法糖(简化代码)
  • 有参装饰器
  • 装饰器练习题(三层装饰器)

今日内容详细

装饰器的概念(重点)

"""
装饰器并不是一个新的知识
	而是我们之前所学的 名称空间 函数对象 闭包函数组合而来
"""
器:指的是工具
装饰:给被装饰对象添加额外的功能

装饰器的原则
	开放封闭原则
    	开放:对扩展开放
        封闭:对修改封闭

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

# 统计index函数的执行时间

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

装饰器简易版本

# 给函数添加统计时间的功能
# def index():
#     print('from index')
#     time.sleep(1)
# 
# import time
# def outer(func):
#     def get_time():
#         start_time = time.time()
#         func()
#         end_time = time.time()
#         print('程序运行时间为:%s'%(end_time-start_time))
#     return get_time
# index = outer(index)
# index()  # 程序运行时间为:1.012636423110962

解决参数问题

# import time
# def index():
#     time.sleep(1)
#     print('开业了')
# def login(name):
#     time.sleep(2)
#     print('%s正在发牌'%name)
# def outer(func):
#     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
# index = outer(index)
# index()  # 程序运行时间为:1.0100035667419434
# login = outer(login)
# login('tom')  # 程序运行时间为:2.0142407417297363

解决返回值问题

# import time
# def index():
#     time.sleep(1)
#     print('开业了')
#     return 'from index'
# def login(name):
#     time.sleep(2)
#     print('%s正在发牌'%name)
#     return 'from login'
# def outer(func):
#     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
#     return get_time
# index = outer(index)
# res = index()  # 程序运行时间为:1.0100035667419434
# print(res)  # from index
# login = outer(login)
# res = login('tom')
# print(res)  # from login

认证装饰器

# 普通版本
# import time
# def index():
#     time.sleep(1)
#     print('开局一把刀 装备全靠爆')
# def home():
#     time.sleep()
#     print('往死里学')
#     # 获取用户输入
# def login_auth(func):
#     def auth(*args,**kwargs):
#         username = input('username>>>:').strip()
#         pwd = input('pwd>>>:').strip()
#         if username == 'jason' and pwd == '123':
#             print('用户%s登录成功' % username)
#             res = func()
#             return res
#         else:
#             print('用户名或密码输入错误')
#     return auth
# index = login_auth(index)
# index()

# 进阶版本
import time
def index():
    time.sleep(1)
    print('开局一把刀 装备全靠爆')
def home():
    time.sleep(1)
    print('往死里学')
# 定义一个用户是否登录
is_login = {'is_login': False}
# 判断用户是否登录
def login_auth(func):
    def auth(*args,**kwargs):
        if is_login.get('is_login'):
            res = func(*args, **kwargs)
            return res
        # 获取用户输入
        username = input('username>>>:').strip()
        password = input('ppasswore>>>:').strip()
        if username == 'jason' and password == '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()

装饰器固定模板

# 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
def index():
    print('from index')

@outer
def home():
    print('from home')

index()
home()

"""
装饰器语法糖书写规范
	语法糖必须紧贴在被装饰对象的上方
装饰器语法糖内部原理
	会自动将下面紧贴的被装饰对象名字当做参数传给装饰器函数调用
"""

双层语法糖

# import time
# def get_time(func):
#     def inner(*args,**kwargs):
#         start_time = time.time()
#         res = func()
#         end_time = time.time()
#         print('程序运行时间为:%s'%(end_time-start_time))
#         return res
#     return inner
# def login_auth(func):
#     def auth(*args,**kwargs):
#         username = input('username>>>:').strip()
#         password = input('password>>>:').strip()
#         if username == 'jason' and password == '123':
#             res = func(*args, **kwargs)
#             return res
#         print('用户名或密码输入错误')
#     return auth
# 
# @login_auth
# @get_time
# def index():
#     time.sleep(1)
#     print('开局一把刀 装备全靠爆')
# index()

# @login_auth
# @get_time
# def home():
#     time.sleep(1)
#     print('往死里学')
# home()

装饰器修复技术

from functools import  wraps
def outer(func):
    @wraps(func)
    def inner(*args,**kwargs):
        print('执行函数之前可以添加的额外功能')
        res = func(*args,**kwargs)
        return res
    return inner

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

print(home)  # 打印函数home的内存地址
help(home)  # 打印函数home解释
help(len)  # 打印函数len解释

posted on 2021-11-17 23:07  Henrywuovo  阅读(53)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3