博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
跟着ALEX 学python day4集合 装饰器
阅读量:7094 次
发布时间:2019-06-28

本文共 5019 字,大约阅读时间需要 16 分钟。

文档内容学习于

 

 

 

装饰器 :

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

原则:

1、不能修改被装饰的函数的源代码

2、不能修改被装饰的函数的调用方式

 

看以下

[root@localhost day4]# cat decorator.py #!/usr/bin/env  python3import  timedef  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                                                               #使用装饰器(这个装饰器的作用其实是统计test1 这个函数的运行时间),然后这个装饰器 对被修饰的 test1这个函数  这个其实是不影响的。  并没有违背以上2条原则。                         def test1():    time.sleep(3)    print  ("this is test")    return  0test1()[root@localhost day4]# ./decorator.py this is testthe func run time  is  3.0033674240112305                             #装饰器的效果 ,统计test1 函数的运行时时间。

 

我们  一步 一步 把装饰器 拆开来 慢慢 理解 。

装饰器的知识储备

1. 函数即“变量”   

这个概念  可以看视屏day4__5.  简单说就是 python通过内存地址(函数名,变量名)来调用变量(函数)。

2.高阶函数

3.嵌套函数

 

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

 

然后 我们 引用

1.函数即“变量” 

2.高阶函数

之前我们提到了 高阶函数的 概念

1.  把一个函数名当做实参传给另一个函数

2. 返回值中包含函数名

 

的概念   其实功能 就类似以下。   但是以下不是装饰器。只是功能类似。因为他违背了2、不能修改被装饰的函数的调用方式 的规则(这个说明只是为了帮助理解)

import  timedef 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()这么写

 PS :

在以上 例子中bar其实是源代码,  虽然我们没有变化bar的源代码 。 但到最后其实调用bar的方式改变了(将bar作为实参使用了)。违背了第2条原则。  所以以上并不是装饰器。

 

 

然后我们上面看到了  高阶函数的  第二条定义

2. 返回值中包含函数名

我们做以下尝试

import  timedef 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()

 

通过以上例子 我们可以发现  

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

 

这样,我们对于高阶函数的定义 ,在装饰器中可以理解为

1.  把一个函数名当做实参传给另一个函数(不修改被装饰函数的情况下不修改源代码 )

2. 返回值中包含函数名(不修改函数的调用方式  )

 

 

 

嵌套函数

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

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

 

看以下

[root@master day4]# cat  decarate.py #!/usr/bin/env  python3x = 0def grandba():    x = 1    def dad():        x = 2        def son():            x = 3            print  (x)        son()    dad()grandba()[root@master day4]# ./decarate.py 3

 

 

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

 

[root@localhost day4]# cat decorator2.py #!/usr/bin/env  python3import  timedef 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() [root@localhost day4]# ./decorator2.py in the test1the func run time is 3.0034003257751465

 

@符

在python3中可以直接使用 @ 符号来调用装饰器。

1.它一定要写在被修饰函数的前面

[root@localhost day4]# cat decorator2.py #!/usr/bin/env  python3import  timedef 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")test1()[root@localhost day4]# ./decorator2.py in the test1the func run time is 3.003570795059204

 

完整的装饰器

装饰器使用传参

理解 一下。  是在理解不了,就死记吧。  要传参就是,需要deco和 func这边也将形参写好。

[root@localhost day4]# cat decorator2.py #!/usr/bin/env  python3import  timedef 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("haha",55)[root@localhost day4]# ./decorator2.py this  is  haha,55the func run time is 1.0164666175842285

 

转载于:https://www.cnblogs.com/rockyricky/p/11009644.html

你可能感兴趣的文章
数据科学面临的共同挑战有哪些?
查看>>
跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
查看>>
MYSQL建表语法(主键,外键,联合主键)
查看>>
Docker容器的IO基准
查看>>
PostgreSQL 在铁老大订单系统中的schemaless设计和性能压测
查看>>
SaaS模式与ASP模式的差异分析报告
查看>>
[译]函数式响应编程入门指南
查看>>
解决tiny4412串口终端不能输入的问题
查看>>
FCN
查看>>
BloomFilter算法概述
查看>>
关于static 访问权限、继承、多态、内部类结合在一起时的使用方法
查看>>
HIMSS博览会首登中国 建言医卫IT新发展
查看>>
苹果将知名黑客Kristin Paget招致麾下
查看>>
【机器学习PAI实践七】文本分析算法实现新闻自动分类
查看>>
SACC 2013:大数据可视化应用及推荐
查看>>
这里有一份面筋请查收(七)
查看>>
在 Cocos2d-x 中使用 OpenSSL
查看>>
Python 进阶_OOP 面向对象编程_self 的实例绑定
查看>>
JAVA在win10上的安装环境配置
查看>>
闵春榕:PCIE SSD在数据库优化中的应用
查看>>