• day12闭包,装饰器


     一、闭包:内部函数引用了外部函数的变量.

    # f1()
    #闭包的定义
    #内部的函数引用了外部函数的变量
    
    # def f1(b):     #闭包的常用状态
    #     def f2():
    #         print(b)
    #     return f2
    #内部函数返回一个值到全局

    # def f1(): #从内部函数返回一个值到全局
    # b = 10
    # def f2():
    # return b
    # return f2()
    #
    # print(f1())

     
    def f1():
        a = 1
        def f2():
            def f3():
                print(a)
            f3()
            print('f3 : ',f3.__closure__)
        f2()
        print('f2 : ',f2.__closure__)
    
    f1()   #__closure__ 用来查看是否是 闭包 cell就是调用的元素  三层的嵌套,f23调用了外层的元素,那么f2也是闭包了

    从某个网页读取网页内容

    from urllib.request import urlopen
    # ret = urlopen('http://www.cnblogs.com/Eva-J/articles/7194277.html').read()
    # print(ret)
    def get_url(url):
        def read1():
            ret = urlopen(url).read()
            print(ret)
        return read1  
    
    read_func = get_url('http://www.cnblogs.com/Eva-J/articles/7194277.html')  #结果是bytes类型。写入文件再打开就完成了转码
    read_func()
    read_func()

    二、装饰器:

    #装饰器的作用
    # 在不改变函数的调用方式的情况下,给函数的前后添加新的功能
    
    #从最简单的装饰器
    def timmer(qqxing):   #timmer是装饰器的名字,传入的参数就是被装饰的函数
        def inner():      #在装饰器中需要定义一个内部函数
            print('调用func之前')
            qqxing()      #被装饰的函数,并且要执行
            print('调用func之后')
        return inner      #将内部函数的名字返回
    
    @timmer   #语法糖  func = timmer(func)
    def func():
        print('公司好老板好同事好')
    
    # func()
    # 完整的装饰-万能的装饰
    def timmer(qqxing):   #timmer是装饰器的名字,传入的参数就是被装饰的函数
        def inner(*args,**kwargs):      #在装饰器中需要定义一个内部函数
            print('调用func之前')
            ret = qqxing(*args,**kwargs)      #被装饰的函数,并且要执行
            print('调用func之后')
            return ret
        return inner      #将内部函数的名字返回
    
    @timmer   #语法糖  func = timmer(func)
    def func(name):
        print('%s的公司好老板好同事好'%(name))
        return 1111111111
    
    ret = func('俊杰')
    print('result : %s'%ret)
    
    #装饰器的固定结构
    def wrapper(func):
        def inner(*args,**kwargs):
            """被装饰函数执行之前要添加的代码"""
            ret = func(*args,**kwargs)
            """被装饰函数执行之后要添加的代码"""
            return ret
        return inner

    两个案例:1.一次认证,多次访问  2.将当前调用函数的日志记录在文件里

    #概念
    #开放封闭原则
    #开放
        #对扩展是开放的
    
    #封闭
        #对修改是封闭的
    
    #装饰器:开放封闭原则
    #一次认证多次免登陆
    flag = False
    def login(func):
        def inner(*args,**kwargs):
            global flag
            if flag == False:
                username = input('用户名:')
                password = input('密码:')
                if username == 'alex' and password == 'somebody':
                    print('登录成功')
                    flag = True
            if flag == True:
                ret = func(*args,**kwargs)
                return ret
        return inner
    
    @login
    def art():
        print('欢迎来到文章页')
    
    @login
    def dar():
        print('欢迎来到日记页')
    
    #用装饰器实现,访问art或者dar函数,登陆一次之后,无需再次登录
    # art()
    # dar()
    
    def log(func):
        def inner(*args,**kwargs):
            print('你要调用%s函数了'%func.__name__)
            ret = func(*args,**kwargs)
            return ret
        return inner
    
    @log
    def f1():
        print('f1')
    @log
    def f2():
        print('f2')
    
    #日志
    f1()
    f2()

    三层装饰器:

    # def auth():
    #     def auth2(func):
    #         def wrapper(*args,**kwargs):
    #             name=input("user: ")
    #             pwd=input("pwd: ")
    #
    #             if True:
    #                 if name == 'egon' and pwd == '123':
    #                     print('login successful')
    #                     res=func(*args,**kwargs)
    #                     return res
    #             else:
    #                 print('ldap')
    #         return wrapper
    #     return auth2
    # @auth()  # foo = auth(driver='file')(foo)  三层的话 语法糖那里要带上括号
    # def foo(name):
    #     print(name)
    # foo('egon')
  • 相关阅读:
    明确目标
    适应环境
    解决问题的方式
    超市收银系统设计
    功能开发流程
    JS代码和OC代码的相互调用
    app上架流程的整理
    手动创建单例
    Python 安装mysqldb
    Python UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-4: ordinal not in range(128)
  • 原文地址:https://www.cnblogs.com/zjchao/p/7783570.html
Copyright © 2020-2023  润新知