zoukankan      html  css  js  c++  java
  • 小白的Python之路 day4 装饰器前奏

    装饰器前奏:

    一.定义:

      1.装饰器本质是函数,语法都是用def去定义的

      (函数的目的:他需要完成特定的功能)

      2.装饰器的功能:就是装饰其他函数(就是为其他函数添加附加功能)

    二.原则:

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

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

    三. 实现装饰器知识储备:

      1.函数即“变量”  (先定义,再调用)

      2.高阶函数

      3.嵌套函数

      4.匿名函数   样式 (calc = lambde x:x*3 )

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

    1. 函数即“变量”

      (1). python的内存机制

    1
    2
    3
    4
    5
    #变量
    = 1
    #函数
    def test():
        pass

         以上一个变量一个函数在内存中的表现形式如下图:

         在python解释器中,有一个概念叫做引用基数,那什么叫引用基数呐,就是比方说,x=1,它会先在内存当中把1这个值试试在在的存放下来,这个x其实就是1的门牌号,也是对1的一次引用。python什么时候把这个1这个屋子清空呐?它会等到1所对应的门牌号都没有了,就会把1这里面的东西给清掉,这个也是python的内存回收机制,就是靠这种方式回收的。

      (2). del清理

        那我们用什么清理呐?用del去清理门牌号,就是对1的值引用的变量,del  x就表示清理掉1对应的x的门牌号。如果x没有被del,则x永远不还被删除,除非程序结束了,不然永远不会被删除。del删除的不是1,只是把门牌号x删除了,只是定期刷新时,发现1没有被其他门牌号引用了,才会被清掉。

      (3). 函数在内存的表现形式

      我们先通过四个例子来解释一下:

      ①bar函数没有定义

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #bar函数没有定义
    def foo():
        print("in the foo")
        bar()
     
    foo()
     
    #输出
    in the foo
    Error:name 'bar'is not defined

      ②bar函数在foo函数之后定义

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #bar函数在foo函数之后定义
    def foo():
        print("in the foo")
        bar()
     
    def bar():
        print("in the bar")
     
    foo()
     
    #输出
    in the foo
    in the bar

      

     ③bar函数是在foo函数之前定义

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # bar函数是在foo函数之前定义
    def bar():
        print("in the bar")
     
    def foo():
        print("in the foo")
        bar()
     
    foo()
     
    #输出
    in the foo
    in the bar

       显然,两种写法效果是一样的,那我们来看看第四种情况。

      ④bar函数在foo函数调用之后声明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # bar函数在foo函数调用之后声明
    def foo():
        print("in the foo")
        bar()
     
    foo()
     
    def bar():
        print("in the bar")
     
    #输出
    Traceback (most recent call last):
    in the foo
      File "D:/PycharmProjects/pyhomework/day4/装饰器/函数即变量.py", line 31in <module>
        foo()
      File "D:/PycharmProjects/pyhomework/day4/装饰器/函数即变量.py", line 29in foo
        bar()
    NameError: name 'bar' is not defined  #bar函数没有定义

    2.高阶函数

    满足下面条件之一就可以称为高阶函数:

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

      b.返回值中包含函数名(调用函数体)

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

    作用:在不修改被装饰函数源代码的情况下为其添加功能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    def bar():
        time.sleep(3)
        print("in the bar")
     
    def test1(func):
        print(func)
        start_time = time.time()
        func()   #run bar
        stop_time = time.time()
        print("the func run the is %s"%(stop_time-start_time))
    #没有修改bar的代码
    test1(bar)  #把bar函数名当做实参传到test1中
     
    #输出
    <function bar at 0x0000000000A7D378>  #bar函数的内存地址
    in the bar
    the func run the is 2.9912972450256348

    2、返回值中包括函数名

    作用:不修改函数调用方式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import  time
     
    def bar():
        time.sleep(3)
        print("in the bar")
     
    def test2(func):
        print(func)
        return func   #返回函数的内存地址
     
    #调用test2函数
    bar = test2(bar) 
    bar()  #没有bar函数改变调用方式
     
    #输出
    <function bar at 0x0000000000B6D378>  #打印bar函数的内存地址
    in the bar
     

     

  • 相关阅读:
    c语言-何为编程?
    c语言-注释
    【转】使用DirectUI技术实现QQ界面
    c语言-error C2440: “static_cast”: 无法从“UINT (__thiscall CHyperLink::* )(CPoint)”转换为“LRESULT (__thiscall CWnd::* )(CPoint)”
    系统分析师【转】
    c语言-经验之谈
    开源托管站点大全
    c语言-扑克牌小魔术
    c语言-猜数字游戏
    世界语简介
  • 原文地址:https://www.cnblogs.com/ManyQian/p/8137462.html
Copyright © 2011-2022 走看看