皓月星空

导航

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()被装饰的属性

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

posted on 2019-08-08 11:39  皓月星空  阅读(4736)  评论(1编辑  收藏  举报