python 装饰器

学习 Alex python 自动化运维开发 装饰器

装饰器:

定义: 装饰器本质是函数,功能是装饰其它函数,为其它函数添加附加功能。
原则:

  • 不能修改被装饰的函数源码
  • 不能修改被装饰函数的调用方式
# -*- coding :  utf-8 -*-
# @Data      : 2020-02-07
# @Author    :  Ming Xu
# @Email     :  920972751@qq.com
# @File      :  decorator.py
# Desctiption:  使用装饰器来统计 test 这个函数的运行时间

import time


def timmer(func):
    def warpper(*args, **kwargs):
        start_time = time.time()
        func()
        stop_time = time.time()
        print("the func run time is %s" % (stop_time - start_time))

    return warpper


@timmer
def test():
    time.sleep(3)
    print("this is test")
    return 0


test()

装饰器的基础知识

高阶函数 + 嵌套函数 -----> 装饰器

  • 函数即变量
  • 高阶函数

把一个函数名当做实参传给另外一个函数
返回值中包含函数名

# -*- coding :  utf-8 -*-
# @Data      :  2020-02-07
# @Author    :  Ming Xu
# @Email     :  920972751@qq.com
# @File      :  decorator_1.py
# Desctiption:  不是装饰器。只是功能类似

"""
把一个函数名当做实参传给另外一个函数
返回值中包含函数名
"""

import time


def bar():  # 定义了bar 这个函数
    time.sleep(3)
    print("in the bar")


def test(func):  # bar作为实参传进来, 这个 其实这个时候func就等于bar 这个函数了
    start_time = time.time()
    func()  # 运行 func这个变量(函数),, 其实就运行了bar这个函数
    stop_time = time.time()
    print("the  func run time  is  %s" % (stop_time - start_time))

test(bar)

说明:虽然我们没有改变bar函数 。 但实际改变了调用 bar 的方式(将bar作为实参使用了)违背了第 2 条原则。 所以以上并不是装饰器。

高阶函数,返回值中包含函数名

# -*- coding :  utf-8 -*-
# @Data      : 
# @Author    :  Ming Xu
# @Email     :  920972751@qq.com
# @File      :  
# Desctiption:  

import time

def bar():
    print("in the bar")


def test(func):
    start_time = time.time()
    func()
    stop_time = time.time()
    print("the  func run time  is  %s" % (stop_time - start_time))
    return func  # 进行这个变量(函数)作为返回值 ,这样这个函数的执行结果就是这个函数的内存地址(这个函数的变量名),就可以定义在外面定义变量了。

bar = test(bar)  # 这样再定义bar,就可以不修改 bar这个源代码的调用方式了。
bar()

返回值中包含函数名的作用相当于不修改函数的调用方式

高阶函数的定义,在装饰器中可以理解为

  • 把一个函数名当做实参传给另一个函数(不修改被装饰函数的情况下不修改源代码 )
  • 返回值中包含函数名(不修改函数的调用方式 )

嵌套函数: 就是在函数里面再定义一个函数


def  foo():
    print("in the foo")
    def  bar ():  #这里定义的bar函数,一定要在foo里面才能调用, 作用类似于局部变量,bar这个函数在全局是不生效的。
        print ("in the  bar")
    bar()
 
foo()

然后将高阶函数和嵌套函数结合起来使用

# -*- coding :  utf-8 -*-
# @Data      : 
# @Author    :  Ming Xu
# @Email     :  920972751@qq.com
# @File      :  
# Desctiption:  高阶函数和嵌套函数一起使用


import time

def timer(func):  # 高阶函数: 把函数作为实参进来
    def deco():  # 嵌套函数:函数里面定义函数
        start_time = time.time()
        func()
        stop_time = time.time()
        print("the func run time is %s" % (stop_time - start_time))

    return deco  # 高阶函数:用函数作为返回值。  这边定义的返回值其实是deco这个函数, 在timer这个函数里面无需执行


def test1():
    time.sleep(3)
    print("in the test1")


test1 = timer(test1)  # 外部调用函数
test1()

在这里插入图片描述
在 python3 中可以直接使用 @ 符号来调用装饰器,它一定要写在被修饰函数的前面

# -*- coding :  utf-8 -*-
# @Data      : 
# @Author    :  Ming Xu
# @Email     :  920972751@qq.com
# @File      :  
# Desctiption:  @ 装饰函数


import time

def timer(func):
    def deco():
        start_time = time.time()
        func()
        stop_time = time.time()
        print("the func run time is %s" % (stop_time - start_time))

    return deco

@timer  # 直接@符加修饰器名字。  但是一定要写在被修饰函数的前面   @time ====    test1=timer(test1)
def test1():
    time.sleep(3)
    print("in the test1")

在这里插入图片描述
装饰器传参

import  time
 
def timer(func):
    def deco(*args,**kwargs):                                   ###  进行传参
        start_time=time.time()
        func(*args,**kwargs)                                    ###  因为这个func函数在这边是直接调用的,不是定义的。所以参数需要deco传进来
        stop_time=time.time()
        print ("the func run time is %s" %(stop_time-start_time))
    return deco
 
 
@timer    #   test2 =  timer(test2)     ==>  其实 test2()== fun() 执行是 deco(),所以test2()传参就是 deco() 传参 再传给func()

def test2(name,age):
    time.sleep(1)
    print ("this  is  %s,%s" %(name,age) )
 
test2("Alex", 22)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值