zoukankan      html  css  js  c++  java
  • python----为什么def里面还有def,这个@wraps是什么

    来自菜鸟教程的指导
    由菜鸟教程可知这就是python的函数装饰器,python一切皆对象

    疑惑


    当看到公司项目的源码时,我这个python菜鸟对此产生了困惑,为什么def内还有def,于是上网查资料,总结了一下这个知识点,可以知道这是一个高阶函数

    高阶函数的定义

    1、函数接收的参数是一个函数名
    2、函数的返回值是一个函数名
    3、满足上述要求的任意一个,就可以称之为高阶函数

    def内的def

    第一步,函数中定义函数

    def hi(name = "hyxk"):
        print("hi() function")
        
        def greet():
            return "greet() function"
        
        def welcome():
            return "welcome() function"
        
        print(greet())
        print(welcome())
        print("back in the hi() function")
        
    hi()
    

    可以得到

    #如果在函数中直接调用greet()或者welcome()会怎么样????
    def hi(name = "hyxk"):
        print("hi() function")
        
        def greet():
            return "greet() function"
        
        def welcome():
            return "welcome() function"
        
        print(greet())
        print(welcome())
        print("back in the hi() function")
        
    greet()
    


    这就会显示greet没有定义,但是无论在哪里都可以调用hi(),却不能直接调用hi()内部的函数。
    这就是函数内嵌套函数。

    第二步,从函数中返回函数

    def hi(name = "hyxk"):
        
        def greet():
            return "greet() function"
        
        def welcome():
            return "welcome() function"
        
        if name == "hyxk":
            return greet
        else:
            return welcome
        
    a = hi()
    print(a)
    #output: <function hi.<locals>.greet at 0x0000025ED10599D8>
    #可以清晰看到 a指向hi()函数中的greet()函数
    
    print(a())
    #output: greet() function
    
    #在if/else的时候,函数返回没有加(),如果加上(),那么就是返回函数的之,而不是返回函数了。
    

    第三步,将函数作为参数给另一个函数

    def hi():
        return "hi yasoob!"
     
    def doSomethingBeforeHi(func):
        print("I am doing some boring work before executing hi()")
        print(func())
     
    doSomethingBeforeHi(hi)
    
    #将hi放到func里面,将hi当成参数可以用来传递,在doSomethingBeforeHi函数内进行执行
    

    第四步,修改上一个代码变成装饰器

    def go_out(func):
        def zhunbei():
            print("穿衣服")
            func()
            print("穿裤子")
        return zhunbei
    
    def huazhuang():
        print("化妆")
    
    huazhuang = go_out(huazhuang)
    #化妆这个函数由准备这个函数包装,就相当于被go_out这个函数的内部函数装饰
    huazhuang()
    
    #一般装饰符就是封装一个函数,并用这样那样的方法来修改他的行为
    

    第五步,有@wraps的装饰器

    from functools import wraps
    
    def go_out(func):
        @wraps(func)
        def zhunbei():
            print("穿衣服")
            func()
            print("穿裤子")
        return zhunbei
    @go_out
    def huazhuang():
        print("化妆")
    
    print(huazhuang.__name__)
    
    #output:huazhuang
    #其实到了这里的时候我有点晕,并不明白是什么回事,感觉这不是没有什么装饰效果吗?
    #但是理解一点粗浅的意思
    

    第六步,蓝本规范

    from functools import wraps
    
    def go_out(f):
        @wraps(f)
        def zhunbei(*args, **kwargs):
            if not chuanyifu:
                return "裸体出门"
            return f(*args, **kwargs)
        return zhunbei
     
    @go_out
    def func():
        return("穿衣服出门")
     
    chuanyifu = True
    print(func())
    
    chuanyifu = False
    print(func())
    
    #由蓝本规范可以看出,func函数被go_out装饰器装饰,如果想执行func(),需要看func(),还需要看func()被装饰的属性
    

    装饰器还有更多的作用,后面有学到的再补充

  • 相关阅读:
    在CentOS 7上安装Docker
    VMware虚拟机上安装CentOS 7
    5、Linux的常用命令
    3.Linux 系统目录结构
    2、Linux的关机方式
    zepto callback
    解callback嵌套
    debugger 调试的一些经验
    Chrome Timeline的指标说明:Blocked、Connect、Send、Wait、Receive
    jquery ajax promise
  • 原文地址:https://www.cnblogs.com/hyxk/p/11320213.html
Copyright © 2011-2022 走看看