zoukankan      html  css  js  c++  java
  • python的闭包与装饰器

    闭包指内部函数对外部函数作用域里变量的引用

    内部函数与外部函数:

    def func():#外部函数
        print("this is func")
        def func1(num):#内部函数
            print("this is func1")

    由于内部函数的声明是在外部函数的作用域内,所以我们在外面是无法调用内部函数的,如何调用?在func()中return func1

    def func():#外部函数
        a=1
        print("this is func")
        def func1():
            print("this is func1")
        return func1
    
    var=func()
    var()

    函数的闭包:

    def func():#外部函数
        a=1
        print("this is func")
        def func1(num):
            print("this is func1")
            print(num+a)
        return func1
    
    var=func()
    var(3)

    让内部函数可以使用外部函数的变量,也就是说调用func()时除了func1() return出来了,外部函数中用到的变量也存活下来了

     闭包内的闭包函数(func1())私有化了变量,完成了数据的封装,类似于面向对象

    mylist=[1,2,3,4,5]
    
    def func(obj):
        print("func:",obj)
        def func1():
            obj[0]+=1
            print("func1:",obj)
        return func1
    
    var=func(mylist)
    var()
    var()
    var()

     del var才宣布闭包生命周期的结束,由于闭包包装了一些数据,所以当大规模使用的时候是对内存不利的

    实现装饰器的时候会利用到闭包,装饰器,语法糖@

    装饰器:

    @func1
    def func():
        print("aaa")

    在我们执行func()时,会首先执行func1()中的内容

    如果我们去掉装饰器@func1,那么func就只会执行print,加上装饰器的话就会添加某些功能。因此装饰器的意义就是不影响原有函数的功能,添加新的功能

    一般用于拿到了别人的第三方api,觉得功能简陋还需要添加功能时,就可以使用装饰器

    def func1(func):
        def func2():
            print("112233")
            return func()
        return func2
    
    @func1
    def myPrint():
        print("hello, this is my print")
        
    myPrint()

    相当于给myPrint函数做了装饰,我们调用的myPrint()=func2()+func(),这里的func是传进来的参数,也就是myPrint本身

    相当于func1(myPrint)()

    整个调用流程:

    func1将被修饰函数myPrint作为参数接收上来

    func1接收到了myPrint后返回内部的func2

    func2返回回来之后,将返回回来的结果继续加上括号

    https://www.cnblogs.com/wangtianning1223/p/14118933.html中的程序其实相当于

    funA(funB(funC))()

    因此funA,funB的执行顺序是相反的,而warp的顺序是正序

    带参数的装饰器,多一层包装接收装饰器参数

    def arg_func(sex):
        def func1(a):
            def func():
                if sex=="man":
                    print("you are man")
                if sex=="woman":
                    print("you are woman")
                return a()
            return func
        return func1
    
    @arg_func(sex="man")
    def man():
        print("work for money")
    
    @arg_func(sex="woman")
    def woman():
        print("work for money")
        
    man()
    woman()

     相当于arg_func(sex)(func)()==>func1()==>func2()==>print("you are man")+man() || print("you are woman")+woman()

    被装饰的函数带参数,只需在最内部函数传入参数即可

    def func1(func):
        def func2(x,y):
            print(x,y)
            x+=5
            y+=5
            return func(x,y)
        return func2
    
    @func1
    def mysum(a,b):#a=a+5,b=b+5使用装饰器修改
        print(a+b)
        
    mysum(1,2)

    注意return func()的时候要把参数xy也返回

    无情的摸鱼机器
  • 相关阅读:
    在 Android 4.1上,分析 input -- android framework 部分 2
    Linux内核spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析
    module_init 和 late_initcall 区别
    在 Android 4.4.4 上,分析 input -- android framework 部分
    Android 输入系统 与 按键
    INIT_WORK和INIT_DELAYED_WORK详解
    Android 中多点触摸协议
    android 电容屏(四):驱动调试之驱动程序分析篇 -- FocalTech
    android 电容屏(三):驱动调试之驱动程序分析篇
    android 电容屏(二):驱动调试之基本概念篇
  • 原文地址:https://www.cnblogs.com/wangtianning1223/p/15619953.html
Copyright © 2011-2022 走看看