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()被裝飾的屬性

裝飾器還有更多的作用,后面有學到的再補充


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM