zoukankan      html  css  js  c++  java
  • 装饰器

    一、函数的嵌套和作用域链

    1.函数的嵌套调用
    def max(x,y):
         m = x if x > y else y
         return m
     def max1(a,b,c,d):
         res1 = max(a,b)
         res2 = max(res1,c)
         res3 = max(res2,d)
         return res3
     print(max1(23,-7,31,11))
    函数的作用嵌套

    2.函数的作用域链

    小范围作用域可以使用大范围的变量,但是反之不行


     def f1():
         a = 1
         def f2():
             def f3():
                 print(a)
             f3()      #1
         f2()
    f1()
    函数的作用域链

    3.函数名

    函数名本质上就是函数的内存地址

    (1)可以被引用

     def func():
         print("in func")
     f =  func
     print(f)    #<function func at 0x0000021011E51E18>
    函数名的本质

    (2)可以被当作容器类型的元素

    函数名
    def f1():
        print("f1")
    def f2():
        print("f2")
    def f3():
        print("f3")
    
    l = [f1,f2,f3]
    d = {"f1":f1,"f2":f2,"f3":f3}
    l[0]()        #f1()
    d["f2"]()     #f2()
    被当作容器类型的元素

    (3)可以当作函数的参数和返回值

    函数名
    def f1():
        print("f1")
    def f2(argv):
        argv()
        return argv
    f = f2(f1)
    f()
    当作函数的参数和返回值

    (4)函数名可以赋值给其他变量

    def func2():
        print(222)
    def func3(x):
        print(a)
        return a
    a = 3
    ret = func3(a)
    print(ret)
    函数名可以赋值给其他变量
    
    
    二、第一类对象(first——clss object)

    1.可运行期创建
    2.可用做函数参数或返回值
    3.可存入变量的实体

    三、闭包

    内层函数,对外层函数(非全局)的变量的引用,叫做闭包
    作用:保护内存


    1.闭包函数

    def wrapper():
        name = "alex"
        def inner():
            print(name)   #alex
        inner()
    wrapper()
    闭包函数

    2.检查是不是闭包

    cell 是闭包,none就不是闭包(面试题)

    def wrapper():
        name = "alex"
        def inner():
            print(name)   #alex
        inner()
        print(inner.__closure__) #cell 是闭包
    wrapper()
    例子1

    在外层函数内部,执行inner()
    def wrapper():
        def inner():
            print(666)
        return inner
    wrapper()()
    
    def wrapper():
        def inner():
            print(666)
        inner()
    wrapper()
    例子2

    3.闭包的用处

    如果说你内存函数是个闭包,python内部有一个
    机制,遇到闭包,他会在内存中开启有一个内存空间,不会关闭。
    避免来回开关,不会随着函数的结束而关闭。
    直到关闭python解释器,或python内部来回巡回,才会关闭

    4.爬虫

    from urllib.request import urlopen
    print(urlopen("http://www.cnblogs.com/jin-xin/articles/8259929.html").read())
    #url 访问某个程序的路径
    #uri 访问某个程序路径的 一部分
    # 协议名   http  https
    # 域名     cnblogs.com
    # 项目名   jin-xin
    # 模块名   articles
    # 页面名   8259929.html
    def index(url):
        content = urlopen(url).read()
        def get():
            with open("爬虫","a") as f1:
                f1.write(content.decode("utf-8"))
        return get
    index("http://www.cnblogs.com/jin-xin/articles/8259929.html")()
    
    
    四、装饰器

    1.什么是装饰器?

    装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,
     装饰器的返回值也是一个函数对象。


    2.装饰器的应用场景


    比如插入日志,性能测试,事务处理,缓存等等场景。

    3.简单的装饰器

    import time
    def timmer(f):
        def inner():
            start_time = time.time()
            time.sleep(0.1)
            f()
            end_time = time.time()
            print("执行效率%s"%(end_time - start_time))
        return inner
    @timmer         #func = timmer(func)
    #语法糖,需要放在你像测试函数上面。没有空格。python内部封装语法糖。python内部机制
    def func():
        print("完成")
    func()
    语法糖

    4.带参数的装饰器

    import time
    def timmer(f):
        def inner(a):
            start_time = time.time()
            time.sleep(0.1)
            f(a)
            end_time = time.time()
            print("执行效率%s"%(end_time - start_time))
        return inner
    @timmer         #func = timmer(func)
    #语法糖,需要放在你像测试函数上面。没有空格。python内部封装了。python内部机制
    
    def func(a):
        print("%s完成"%a)
    func("萌哥")
    带参数装饰器例子1
    import time
    flag = True
    def timmer_out(flag):
        def timmer(func):
            def inner(*args,**kwargs):
                if flag :
                    start = time.time()
                    time.sleep(0.3)
                    ret = func(*args,**kwargs)
                    end = time.time()
                    print("执行效率%s"%(end - start))
                    return ret
                else:
                    ret = func(*args,**kwargs)
                    return inner
    
            return inner
        return timmer
    
    @timmer_out(flag)            #1.先判断一下,True或者False 2. @timmer
    def f1():
        print(666)
    @timmer_out(flag)
    def f2():
        print(777)
    f1()
    f2()
    带参数装饰器例子2

       5.带返回值装饰器

    import time
    def timmer(f):                      #func
        def inner(*args,**kwargs):      #"萌哥"
            start_time = time.time()
            time.sleep(0.1)
            ret = f(*args,**kwargs)     #func("萌哥"),ret==222
            end_time = time.time()
            print("执行效率%s"%(end_time - start_time ))
            return ret
        return inner
    @timmer   #func = timmer(func)
    def func(a):
        return 222
    print(func("萌哥"))  222
    带返回值的的装饰器

      6.通用装饰器

    def wrapper(func):
        def inner(*args,**kwargs):
            "执行函数前的操作"
            ret = func(*args,**kwargs)
            "执行函数后的操作"
            return ret
        return inner
    @wrapper
    def func(a):
        print(1)
    print(func(a))
    通用解释器

     7.多个装饰器装饰一个函数

    def wrapper1(func):
        def inner():
            print("wrapper1,before func")
            func()
            print("wrapper1,after func")
        return inner
    def wrapper2(func):
        def inner():
            print("wrapper2,before func")
            func()
            print("wrapper2,after func")
    @wrapper2
    @wrapper1
    def f():
        print("in f")
    f()
    多个装饰器装饰一个函数
    五、补充知识

    1.
    函数的有用信息

    def f1():
        '''
        本函数的功能:绘图功能,实时接收数据并绘图.
        :return: 绘图需要的数据,返回给前端某标签
        '''
        print(f1.__doc__)
        print(f1.__name__)
        print(666)
    f1()
    
    
    # print(f1.__doc__)  #获取函数的说明信息
    # print(f1.__name__)  # 获取函数的名字
    函数的有用信息

       2.开放封闭原则

       1.对扩展是开放的
    
       2.对修改是封闭的

       3.  *

    在执行函数时,加*时打散。
    在接受函数时,加*时聚合
    def f1(*args,**kwargs):
        print(args)   # (1, 2, 3, 4)
        # 执行函数时,不加*是聚合。接受函数时加*时聚合
        print(*args)   #1 2 3 4
        # 执行函数时打散,没有任何数据类型 。print()也是一个函数
    f1(1,2,3,4)
    
    def f1(*args,**kwargs):
        print(args)   # (1, 2, 3, 4)
        # 执行函数时,不加*是聚合。接受函数时加*时聚合
        print(*args)   #1 2 3 4
        # 执行函数时打散,没有任何数据类型 。print()也是一个函数
    f1(*[1,2,3,4])
    加*的作用
     


  • 相关阅读:
    跨站脚本攻击
    性能测试总述
    转:KPI(Key Performance Indicator,关键绩效指标)
    《C#与.NET3.5高级程序设计(第4版)》笔记2
    三层架构的一点小小的认识(很小很小)
    《C#与.NET3.5高级程序设计(第4版)》笔记3
    windows 2008无线网络"没有正确配置为使用IP协议" 错误解决办法
    《C#与.NET3.5高级程序设计(第4版)》笔记6
    A+=B和A=A+B真的有区别吗
    《C#与.NET3.5高级程序设计(第4版)》笔记5
  • 原文地址:https://www.cnblogs.com/lara0520/p/8460509.html
Copyright © 2011-2022 走看看