python----为什么def里面还有def,这个@wraps是什么

Posted hyxk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python----为什么def里面还有def,这个@wraps是什么相关的知识,希望对你有一定的参考价值。

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

疑惑

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

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

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

以上是关于python----为什么def里面还有def,这个@wraps是什么的主要内容,如果未能解决你的问题,请参考以下文章

Python用def函数法打印100到200以内所有的奇数?

15python---def函数

15python---def函数

Python 里面什么时候用一个=,什么时候用两个=

在python中把方程参数设置为任意方程?def(self,f)

python语法教程——def()函数