• 20201203 装饰器之高阶函数


    实现装饰器知识储备:
    1. 函数即“变量”
    2. 高阶函数
       a: 把一个函数名当做实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
       b: 返回值中包含函数名(不修改函数的调用方式)
    3. 嵌套函数
    
    高阶函数 + 嵌套函数 ==> 装饰器
    1-1
    def bar():
        print('in the bar')
    
    def test1(func):
        print(func)
    
    test1(bar)
    --->
    <function bar at 0x0000019DE00C4828>
    打印的是内存地址
    1-1-2
    >>> def bar():
    ...     pass
    ...
    >>> bar
    <function bar at 0x0000024FC0894948>
    bar 是一个门牌号,帮助找到房间的位置而已。
    所以,门牌号(内存地址)出来了
    
    实际上 bar(),bar + 小括号,就是在基于内存地址,进行调用。
    1-1-3
    def bar():
        print('in the bar')
    
    def test1(func):
        print(func)
        func()
    
    test1(bar)
    --->
    <function bar at 0x0000024FC0894AF8>
    in the bar
    
    bar 就是一个门牌号,门牌号是一个映射的地址。
    加小括号,就能运行。
    
    bar传给 func后
    相等于 func = bar 所以 func() 相当于 bar()
    
    函数即变量
    x=1
    y=x 
    bar是一个函数,可以像变量一样来回赋值。
    1-1-4 
    为什么要把 bar 传到 test1 中运行呢?直接运行不行吗?
    def bar(): print('in the bar') def test1(func): print(func) func() test1(bar) bar() ---> <function bar at 0x000001904E9A4828> in the bar in the bar 因为如果发生改动,比如 import time def bar(): time.sleep(3) print('in the bar') def test1(func): start_time = time.time() func() # run bar stop_time = time.time() print("the func run time is %s" %(stop_time-start_time)) test1(bar) # 最后统计出的是bar的运行时间
    1-1-5
    装饰函数
    原来就是  bar()
    运行结果 in the bar 
    现在写了高阶函数
    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    
    def test1(func):
        start_time = time.time()
        func()      # run bar   可以在不修改源代码的情况下,为源代码加上功能
        stop_time = time.time()
        print("the func run time is %s" %(stop_time-start_time))
    test1(bar)
    首先正常运行 bar 函数 
    test1 是高阶函数,附加了计算 bar 函数 运行时间的功能。
    --->
    in the bar
    the func run time is 3.0009982585906982
    装饰器:
    定义:本质是函数,(装饰其他函数)就是为其他函数添加附加功能
    test1 是装饰器 要装饰别人的,bar 才是源代码
    不同的是调用方式变了
    2 返回值中可以包含函数名
    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    def test2(func):
        print(func)
        return func
    
    test2(bar)
    --->
    <function bar at 0x000002355E45D8B8>
    将首先打印 bar 函数的内存地址,所以
    print(test2(bar))
    --->
    <function bar at 0x000002355E45D8B8>
    <function bar at 0x000002355E45D8B8>
    才可以看出效果,bar传给func,打印 func 返回内存地址,第二个打印值,就是 print 的运行结果
    有内存地址就意味着,加上小括号就可以运行
    2-1
    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    def test2(func):
        print(func)
        return func
    
    test2(bar)
    # 直接写 bar 相当于把内存地址传给 func 了
    # 加上小括号相当于把 bar 的返回值传给 func 了,这样就不符合高阶函数的定义了
    2-2
    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    def test2(func):
        print(func)
        return func
    
    t=test2(bar)
    print(t)
    --->
    <function bar at 0x00000207B962D8B8>
    <function bar at 0x00000207B962D8B8>
    怎么能让它有用呢??
    t=test2(bar)
    t() # run bar
    --->
    <function bar at 0x000001CBC36FD8B8>
    in the bar
    2-3 bar 只是一个门牌号,可以任意占用,覆盖之前的 bar
    import time
    def bar():
        time.sleep(3)
        print('in the bar')
    def test2(func):
        print(func)
        return func
    
    bar=test2(bar)
    bar()
    # 这样能够运行吗?
    --->
    <function bar at 0x000002F49C12D8B8>
    in the bar
    相当于 test2 已经加上了 新功能,函数的调用方式没有改变
  • 相关阅读:
    扩充Visual Studio 功能
    如何分层啊?
    DirectXInput
    关于分享
    消息机制
    C# 开启一个新进程,IE,打开一个URL,第一次总失败,刷新一下就好了
    远程调试IIS服务器的ASP.NET2.0网站
    IIS 用户 NT AUTHORITY\NETWORK SERVICE 登录失败解决方法
    SharePoint 2010微软Technet讲座第一讲笔记(2011年3月9日发布)
    IIS 未能加载文件或程序集 system.web.extensions解决方法
  • 原文地址:https://www.cnblogs.com/azxsdcv/p/14077765.html
Copyright © 2020-2023  润新知