zoukankan      html  css  js  c++  java
  • 闭包,装饰器

    一、闭包函数

     1、简介

    #闭:指的是闭包函数是定义在一个函数内部的函数
    #包:该内部函数包含外层函数作用域名字的引用(内外函数中间部分)
    
      需要结合函数对象的概念(return内部函数名),将闭包函数返回到全局作用域去使用,从而打破函数的层级限制
    
    #特点:1.定义在另一个函数内的函数
        2.内部的的函数访问了外部的名称(数据)    注意:不包含全局的

    二、为何用闭包函数   

    #闭包函数提供了一种为函数体传值的解决方案

    如何用闭包函数

        def outter():
            x=111
            def inner():
                print(x)
            return inner
    
        f=outter() #f=outter内的inner
        f()
    #定义闭包函数,内层函数看成是定义一个变量,函数名是变量名
    def outer():
        a=10
        return a
    f=outer()
    print(f)
    
    def outer():
        def inner():        #类似a=10
            pass
        return inner         #类似return a
    f=outer()                 执行外层函数,拿到的是内层函数的内存地址
    print(f)
    f()
    加深对创建闭包函数的理解

    为函数传值的两种方式

    def func(x,y):
         print(x+y)
    
    func(1,2)
    为函数体传值的方式一:参数
     def outter(x,y):
         # x=1
         # y=2
         def func():
             print(x+y)
         return func
    
     f=outter(1,2)
     f()
    为函数体传值的方式二:闭包
    #直接通过参数传参
    def get(url):
        response=requests.get(url)
        if response.status_code == 200:
            print(len(response.text))
    get('https://www.baidu.com')    #来一次就需要输入完整的路径,较麻烦
    get('https://www.baidu.com')
    get('https://www.baidu.com')
    get('https://www.tmall.com')
    
    #即使指定,这是全局作用域,任何函数都能访问到都能访问到,
        url1='https://www.baidu.com'
        url2='https://www.tmall.com'
        get(url1)
        get(url1)
    
        get(url2)
        get(url2)
    ------------------------------------------------------------------------
    
    #通过闭包函数传参
    def bar(url):
        def get():
            response=requests.get(url)
            if response.status_code == 200:
                print(len(response.text))
        return get
    baidu=bar('https://www.baidu.com')    #指定好一个,下次直接使用,是绑定的关系
    baidu()
    baidu()
    baidu()
    tmall=bar('https://www.tmall.com')     #将该地址绑定给tmall
    tmall()
    例子

    二、闭包函数之装饰器

    1、简介

    #装饰器就是用一个函数去扩展另一个已存在的函数的功能
    #饰器其实是闭包函数的一种应用方式
    
    #装饰器的原则:
      1、不修改装饰对象的源代码
      2、不修改被装饰对象的源代码
    #装饰器的目标:
      在遵循1和2的条件下,为被装饰对象添加新功能

    2、使用

    无参装饰器

    import time
    def index():
        print('from index')
        time.sleep(3)
    
    def wrapper(func):
        def inner():
            start=time.time()
            func()
            stop = time.time()
            print('run time %s' %(stop-start))
        return inner
    
    
    #闭包函数,f=inner的内存地址
    f = wrapper(index)     #index = wrapper(index)   变量名可随意命名
    f()                             #index()
    最简单的无参装饰器

     有参装饰器

    def auth(data_param):
        def func_outer(func_param):
            def func_inner(*args,**kwargs):
                if data_param == 'login':
                    print('login interface-------')
                    name = input("user: ")
                    pwd = input("pwd: ")
                    if name == 'pdun' and pwd == '123':
                        print('login successful')
                        res=func_param(*args,**kwargs)
                        return res
    
                elif data_param == 'register':
                    print('register interface--------- ')
                    name = input("user: ")
                    pwd = input("pwd: ")
                    print('register successful ')
            return func_inner
        return func_outer
    
    
    #来到这一行,看见函数加括号,就不考虑@,先执行函数,也就是拿到return值,func_outer
    #相当于这一行变为@func_outer,此时函数没有括号,此时就会把正下方的函数当作参数,传给func_outer,就是func_outer(func)
    #并且会把return返回给正下方的函数,func=func_inner
    
    @auth('register')
    def func(name):
        print('hello
    %s'%name)
        return
    
    func('pdun')
    
    @auth('login')
    def func(name):
        print('hello
    %s'%name)
    
    func('Moker')
    
    -----------------------------
    register interface--------- 
    user: qq
    pwd: qq
    register successful 
    login interface-------
    user: pdun
    pwd: 123
    login successful
    hello
    Moker
    View Code

     语法糖

    import time
    def outer(x):
        def inner(*args,**kwargs):
            s=time.time()
            res=x(*args,**kwargs)
            o=time.time()
            return res
        return inner
    
    @outer
    def func(name):
        time.sleep(1)
        print('my name is %s' %(name))
        return 0
    
    func('pdun')
    语法糖
    import functools
    def wapper(func):
        # @functools.wraps(func)       保留函数的元信息
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
    
        return inner
    
    @wapper
    def f1():
        pass
    
    print(f1.__name__)
    
    
    ----------------------------
    inner
    解开注释后
    f1
    functools工具
  • 相关阅读:
    Hibernate HQL查询:
    Struts2里如何取得request,session,application
    Hibernate 报错org.hibernate.PropertyAccessException: IllegalArgumentException(已解决)
    PHP 读取文件的几种方法
    PHP 关于文件操作的简单介绍
    VB 中ListView 某一列的颜色添加不上去的解决方法
    SQL Server 版本号汇总
    C# 单元测试
    Web Api单元测试写法
    git bash 出现vim的时候怎么退出
  • 原文地址:https://www.cnblogs.com/pdun/p/10269289.html
Copyright © 2011-2022 走看看