python装饰器(详解)

2023-05-16

1、什么是装饰器
器指的是工具,可以定义成成函数
装饰指的是为其他事物添加额外的东西点缀

合到一起的解释:
    装饰器指的定义一个函数,该函数是用来为其他函数添加额外的功能
    就是拓展原来函数功能的一种函数

2、为何要用装饰器
开放封闭原则
开放:指的是对拓展功能是开放的
封闭:指的是对修改源代码是封闭的

装饰器就是在不修改被装饰器对象源代码以及调用方式的前提下为被装饰对象添加新功能

   

3、如何用# 需求:在不修改index函数的源代码以及调用方式的前提下为其添加统计运行时间的功能
 

def index(x, y):
    time.sleep(3)
    print('index %s %s' % (x, y))


index(111, 222)
# index(y=111,x=222)
# index(111,y=222)

 

# 解决方案一:失败
# 问题:没有修改被装饰对象的调用方式,但是修改了其源代码

import time


def index(x, y):
    start = time.time()
    time.sleep(3)
    print('index %s %s' % (x, y))
    stop = time.time()
    print(stop - start)


index(111, 222)

  
# 解决方案二:失败
# 问题:没有修改被装饰对象的调用方式,也没有修改了其源代码,并且加上了新功能
#      但是代码冗余

import time


def index(x, y):
    time.sleep(3)
    print('index %s %s' % (x, y))


start = time.time()
index(111, 222)
stop = time.time()
print(stop - start)

 
# 解决方案三:失败
# # 问题:解决了方案二代码冗余问题,但带来一个新问题即函数的调用方式改变了

import time


def index(x, y):
    time.sleep(3)
    print('index %s %s' % (x, y))


def wrapper():
    start = time.time()
    index(111, 222)
    stop = time.time()
    print(stop - start)


wrapper()

 
# 方案三的优化一:将index的参数写活了

import time


def index(x, y, z):
    time.sleep(3)
    print('index %s %s %s' % (x, y, z))


def wrapper(*args, **kwargs):
    start = time.time()
    index(*args, **kwargs)  # index(3333,z=5555,y=44444)
    stop = time.time()
    print(stop - start)


wrapper(3333, 4444, 5555)
wrapper(3333, z=5555, y=44444)

   
# 方案三的优化二:在优化一的基础上把被装饰对象写活了,原来只能装饰index

import time

def index(x,y,z):
    time.sleep(3)
    print('index %s %s %s' %(x,y,z))

def home(name):
    time.sleep(2)
    print('welcome %s to home page' %name)


def outter(func):
    # func = index的内存地址
    def wrapper(*args,**kwargs):
        start=time.time()
        func(*args,**kwargs) # index的内存地址()
        stop=time.time()
        print(stop - start)
    return wrapper

index=outter(index) # index=wrapper的内存地址
home=outter(home) # home=wrapper的内存地址


home('egon')
# home(name='egon')

   
# 方案三的优化三:将wrapper做的跟被装饰对象一模一样,以假乱真

import time

def index(x,y,z):
    time.sleep(3)
    print('index %s %s %s' %(x,y,z))

def home(name):
    time.sleep(2)
    print('welcome %s to home page' %name)

def outter(func):
    def wrapper(*args,**kwargs):
        start=time.time()
        res=func(*args,**kwargs)
        stop=time.time()
        print(stop - start)
        return res


    return wrapper


# # 偷梁换柱:home这个名字指向的wrapper函数的内存地址

home=outter(home)


res=home('egon') # res=wrapper('egon')
print('返回值--》',res)

 

那么我们思考如何方案三的基础上不改变函数的调用方式?
代码如下:# 语法糖:让你开心的语法

import time


# 装饰器
def timmer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        stop = time.time()
        print(stop - start)
        return res

    return wrapper


# 在被装饰对象正上方的单独一行写@装饰器名字
@timmer # index=timmer(index)
def index(x, y, z):
    time.sleep(3)
    print('index %s %s %s' % (x, y, z))


@timmer # home=timmer(ome)
def home(name):
    time.sleep(2)
    print('welcome %s to home page' % name)


index(x=1, y=2, z=3)
home('egon')

   

总结无参装饰器模板

def outter(func):
    def wrapper(*args, **kwargs):
        # 1、调用原函数
        # 2、为其增加新功能
        res = func(*args, **kwargs)
        return res

    return wrapper

为什么说这个就是无参装饰器模板呢?
我们用一个例子来说明:
需求 :写个认证功能(输入账号密码,进行认证),当然账号密码是要从文件中取出。

def auth(func):
    def wrapper(*args, **kwargs):
        # 1、调用原函数
        # 2、为其增加新功能
        name = input('your name>>: ').strip()
        pwd = input('your password>>: ').strip()
        if name == 'egon' and pwd == '123':
            res = func(*args, **kwargs)
            return res
        else:
            print('账号密码错误')

    return wrapper


@auth
def index():
    print('from index')

  

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python装饰器(详解) 的相关文章

随机推荐

  • 统计员工年度,月度的加班和调休统计

    根据需求 xff0c 写了一个统计部门员工年度的加班与调休统计报表 实现结果如下 xff1a 页面代码如下所示 xff1a 64 model IEnumerable lt lvElecCenter Areas HR Models Leave
  • 我的2014-前进在梦想的道路上

    离2014的结束还有2天 xff0c 一年终去 xff0c 感触颇多 xff1a 或是振奋 xff0c 或是感动 xff0c 或是美好 停下手头繁忙的工作 xff0c 静下心来 xff0c 我们一起 来 盘点这一年的工作和生活 这一年你是否
  • 云计算知识3:弹性计算云EC2的基本架构

    弹性计算云EC2主要特性 灵活性 xff1a EC2允许用户对运行实例类型 数量自行配置 xff0c 还可以选择实例运行的地理位置 xff0c 根据用户的需求随时改变实例的使用数量 低成本 xff1a EC2使得企业不必为暂时的业务增长而购
  • 如何将一个网络分为两个子网、如何通过已知IP和子网掩码计算其同一网段的主机IP

    IPV4的IP地址格式通常表示为xxx xxx xxx xxx xff0c 其中xxx为十进制数 xff0c 取值范围是 0 xff0c 255 xff0c 若用16进制表示则为xx xx xx xx xff0c 其中xx的取值范围是 0
  • Unity3D 人称设置(第一人称视角、第三人称视角)

    设置第一人称视角 1 把物体的坐标和摄像机的坐标设置成一样的 xff0c 这样摄像机就在物体内部 xff0c 就是第一人称的视角 2 把摄像机拖拽进物体对象内 xff0c 摄像机变成物体的子对象 xff0c 这样摄像机就能跟着物体一起移动
  • Unity3D 射击游戏练习实例

    知识点 xff1a 刚体组件 xff08 rigidbody xff09 xff0c 受力和碰撞的组件触发器 xff08 Trigger xff09 xff0c 开启后物体碰撞效果取消 xff0c 但仍会返回碰撞消息复制物体对象 xff1a
  • Cocos2dx 环境搭建

    Cocos2dx 环境搭建 准备软件和工具包 xff0c 参考 xff1a Cocos2dx 入门学习准备安装visual studio 安装Python2 7 xff08 直接默认下一步就可以 xff0c 要注意Python安装的路径 x
  • 缺失MSVCR相关文件怎么办

    根据系统的提示 xff0c 看缺失的是哪个文件 xff0c 正常是msvcr100 120 dll在百度上搜索对应文件下载把下载好的msvcr文件 xff0c 放到 C Windows SysWOW64 目录下正常msvcr文件会缺失好几个
  • Cocos2dx 源码解释

    程序入口 AppDelegate AppDelegate在AppDelegate h中定义的 AppDelegate h中的AppDelegate类 xff1a AppDelegate类下的applicationDidFinishLaunc
  • Visual Studio 2019(VS2019) 基本操作

    卸载 加载项目 1 卸载项目 xff1a 不删除项目代码 xff0c 但是停止对该项目的一切使用和调用 xff08 好处是保留代码 xff09 2 加载项目 xff1a 重新加载已停用的项目 xff0c 可以继续使用和调用 修改VS主题风格
  • Elasticsearch 中文分词&多词搜索&权重

    目录 中文分词器 一 安装中文分词器ik 二 使用中文分词器 多词搜索 权重 中文分词器 一 安装中文分词器ik 源码地址 xff1a https github com medcl elasticsearch analysis ik 根据提
  • C# do while循环结构

    注意 循环结构一共有三种 xff1a while循环 https blog csdn net shenqiankk article details 96299600do while循环for循环 https blog csdn net sh
  • C# for循环结构

    注意 循环结构一共有三种 xff1a while循环 https blog csdn net shenqiankk article details 96299600do while循环 https blog csdn net shenqia
  • C# 构造方法(函数)

    构造方法的作用 构造方法用来创建对象 xff0c 并且在构造方法中对对象进行初始化 构造方法的特殊性 没有返回值 xff0c 不需要写类型 xff0c 连void都不要写 构造方法的方法名 xff0c 与类名要相同 构造方法结构 publi
  • GDI+ 绘图方法

    GDI绘直线步骤 创建GDI对象 xff1a Graphics g 61 this CreateGraphics 创建画笔对象 xff1a Pen pen 61 new Pen Brushes Red 创建两个点 xff1a Point p
  • C# 连接MySQL数据库

    C 引用MySQL步骤 xff1a 下载mysql data dll xff1a http soft onlinedown net soft 618668 htm将文件放在项目目录下在VS2019项目内 xff0c 引用mysql data
  • Navicat of MySQL连接和使用

    请先安装MySQL服务 MySQL数据库安装 xff1a https blog csdn net shenqiankk article details 99756531 新建连接 如果出现Can t connect to MySQL ser
  • Mysql创建数据库字符集的选择

    转载 xff1a https blog csdn net JingChC article details 82908686 字符集选择 xff1a 在国内正常都是用 UTF 8 排序选择 xff1a 排序一般分为两种 xff1a utf b
  • Linux进程状态解析 之 R、S、D、T、Z、X (主要有三个状态)

    linux是一个多用户 xff0c 多任务的系统 xff0c 可以同时运行多个用户的多个程序 xff0c 就必然会产生很多的进程 xff0c 而每个进程会有不同的状态 Linux进程状态 xff1a R TASK RUNNING xff0c
  • python装饰器(详解)

    1 什么是装饰器 器指的是工具 xff0c 可以定义成成函数 装饰指的是为其他事物添加额外的东西点缀 合到一起的解释 xff1a 装饰器指的定义一个函数 xff0c 该函数是用来为其他函数添加额外的功能 就是拓展原来函数功能的一种函数 2