Python裝飾器

快到皖裡來發表於2021-02-15

裝飾器用來裝飾函式
返回一個函式物件
“被裝飾函式識別符號”指向“返回的函式物件”
語法糖 @dec

裝飾器基本構造流程(類比閉包)

#裝飾器是對閉包原理的應用

def dec(func):
    print('CALL DEC')
    def in_dec(*arg):        
        print('in_dec arg = :',arg)   #測試arg引數呼叫         
        if len(arg)==0:
            return 0
        for val in arg:
            if not isinstance(val,int):
                return 0 
        return func(*arg)
    
    return in_dec


@dec   #@dec的作用等價於my_sum=dec(my_sum)
def my_sum(*arg):
    print('in my_sum')
    return sum(arg)

#Output:CALL DEC
print(my_sum(1,2,3,4,5))

#Output:in_dec arg = : (1, 2, 3, 4, 5)
#		in my_sum
#		15

在這裡插入圖片描述

被裝飾函式的返回值

def deco(func):
    def in_deco():
        print('in deco')
        func()
    print('call deco')
    return None
    
@deco   #deco(bar)==>返回None,bar=None
def bar():
    print('in bar')
    
print(type(bar))

#Output:call deco
#		<class 'NoneType'>
def deco(func):
    def in_deco():
        print('in deco')
        func()   #bar引數傳遞給func,賦值給閉包in_deco的closure屬性
    print('call deco')
    return in_deco
    
@deco   #deco(bar)==>返回in_decp,bar指向in_decp這個函式
def bar():
    print('in bar')
    
print(type(bar))
bar()

#Output:call deco
#		<class 'function'>
#		in deco
#		in bar

“有引數的裝飾器”構造

def deco(func):
    def in_deco(x,y):
        print('in deco')
        func(x,y)   #bar引數傳遞給func,賦值給閉包in_deco的closure屬性
    print('call deco')
    return in_deco
###############################
#deco(bar)==>in_deco
#bar=in_deco
#bar() indeco()-->bar()
###############################
@deco   #deco(bar)==>返回in_decp,bar指向in_decp這個函式
def bar(x,y):
    print('in bar',x+y)
    
print(type(bar))
bar(1,2)

#Output:call deco
#		<class 'function'>
#		in deco
#		in bar 3

閉包參考https://blog.csdn.net/cymy001/article/details/78125192

#閉包

def my_sum(*arg):
    print('in my_sum')
    return sum(arg)

def dec(func):
    
    def in_dec(*arg):        
        print('in_dec arg = :',arg)   #測試arg引數呼叫         
        if len(arg)==0:
            return 0
        for val in arg:
            if not isinstance(val,int):
                return 0 
        return func(*arg)
    
    return in_dec

my_sum=dec(my_sum)
#呼叫dec,返回in_dec函式;在in_dec閉包裡引用了傳遞的my_sum函式
#用dec(my_sum)的返回值給my_sum賦值,my_sum指向in_dec
#所以,呼叫my_sum時,首先呼叫in_dec;然後呼叫傳遞給func的引數my_sum


print(my_sum(1,2,3,4,5))
print(my_sum(1,2,3,4,5,'6'))
#Output:in_dec arg = : (1, 2, 3, 4, 5)
#		in my_sum
#		15
#		in_dec arg = : (1, 2, 3, 4, 5, '6')
#		0


#呼叫順序:step1,呼叫in_dec函式;step2,呼叫func引數對應的my_sum函式;
#即所有引數先交給in_dec處理,再由my_sum進行計算

相關文章