由淺入深,走進Python裝飾器-----第二篇:進階1--函數裝飾函數

上一篇:由淺入深,走進Python裝飾器-----第一篇:基礎

  1. 裝飾器可以嵌套使用

  2. 裝飾器可以是類,也可以是函數;  裝飾器可以修飾函數,也可以修飾類

  3. 裝飾器的使用種類:

    1. @函數

         被裝飾函數

    2. @函數

          被裝飾類

    3. @類

          被裝飾函數

    4. @類

          被裝飾類


@函數

   被裝飾函數


  • 對帶參數的原函數進行修飾

  • 默認將old函數的參數傳給outer裏面的第一層函數

def outer(f):
	def inner(var):
		print("1 我是outer函數,接收外部傳進來的old :",f)
		print("1 我是outer函數,接收外部傳進來的old的參數 :",var)
		f(var)
		print("3 我是outer函數,我在old函數後顯示")
	return inner
	
	def inner2(var):
	    pass

@outer                                     #old = outer(old)
def old(var):
	print("2 我是old函數","參數: "var)

var = '音樂'                                                
old(var)

>>>1 我是outer函數,接收外部傳進來的old :       <function old at 0x00000000024DAA60>
>>>1 我是outer函數,接收外部傳進來的old的參數 : 音樂
>>>2 我是old函數, 參數:音樂
>>>3 我是outer函數,我在old函數後顯示


  • 對多參數的原函數進行修飾

def outer(f):
	def inner(a, b,*args,d,**kwargs):
	    tmp = d                                            #通過變量接收命名關鍵字參數傳進來的參數,然後再傳遞給內部調用的函數                          
		print("1 我是outer函數,接收外部傳進來的old :",f)
		print("1 我是outer函數,接收外部傳進來的old的參數 :\
			普通參數a={}, 默認參數b={}, 多餘的普通參數:{}和{}".format(a,b,args[0],args[1]))
		print("1 我是outer函數,接收外部傳進來的old的參數 :\
			命令關鍵字參數d:{}, 多餘的關鍵字參數:{}和{}".format(d,kwargs["key1"],kwargs["key2"]))
		f(a,b, *args,d = tmp,**kwargs)
		print("3 我是outer函數,我在old函數後顯示")
	return inner


@outer                                     #old = outer(old)
def old(a, b=2, *args,d,**kwargs):         #五種參數
	print("2 我是old函數",
		"普通參數a={0}, 默認參數b={1}, 多餘的普通參數:{2}和{3},\
		命令關鍵字參數d:{4}, 多餘的關鍵字參數:{5}和{6}"\
		.format(a,b,args[0],args[1],d,kwargs["key1"],kwargs["key2"]))
dict1 = {"key1":"value1","key2":"value2"}
old(1,22,'args1','args2',d=4,**dict1)

>>> 1 我是outer函數,接收外部傳進來的old :        <function old at 0x00000000024AAAE8>
>>> 1 我是outer函數,接收外部傳進來的old的參數 :  普通參數a=1, 默認參數b=22, 多餘的普通參數:args1和args2
>>> 1 我是outer函數,接收外部傳進來的old的參數 :  命名關鍵字參數d:4, 多餘的關鍵字參數:value1和value2
>>> 2 我是old函數 普通參數a=1, 默認參數b=22, 多餘的普通參數:args1和args2,命名關鍵字參數d:4, 多餘的關鍵字參數:value1和value2
>>> 3 我是outer函數,我在old函數後顯示


  • 對多參數的原函數進行嵌套修飾

def outer(f):
	def inner(a, b,*args,d,**kwargs):
	    tmp = d                                            #通過變量接收命名關鍵字參數傳進來的參數,然後再傳遞給內部調用的函數                          
		print("1 我是outer函數,接收外部傳進來的old :",f)
		print("1 我是outer函數,接收外部傳進來的old的參數 :\
			普通參數a={}, 默認參數b={}, 多餘的普通參數:{}和{}".format(a,b,args[0],args[1]))
		print("1 我是outer函數,接收外部傳進來的old的參數 :\
			命令關鍵字參數d:{}, 多餘的關鍵字參數:{}和{}".format(d,kwargs["key1"],kwargs["key2"]))
		f(a,b, *args,d = tmp,**kwargs)
		print("3 我是outer函數,我在old函數後顯示")
	return inner

@outer                         #old = outer(outer(old))
@outer                         #old = outer(old)
def old(a, b=2, *args,d,**kwargs):         #五種參數
	print("2 我是old函數",
		"普通參數a={0}, 默認參數b={1}, 多餘的普通參數:{2}和{3},\
		命令關鍵字參數d:{4}, 多餘的關鍵字參數:{5}和{6}"\
		.format(a,b,args[0],args[1],d,kwargs["key1"],kwargs["key2"]))
dict1 = {"key1":"value1","key2":"value2"}
old(1,22,'args1','args2',d=4,**dict1)

>>> 1 我是outer函數,接收外部傳進來的old :         <function outer.<locals>.inner at 0x00000000024FAAE8>
>>> 1 我是outer函數,接收外部傳進來的old的參數 :   普通參數a=1,  默認參數b=22,  多餘的普通參數:args1和args2
>>> 1 我是outer函數,接收外部傳進來的old的參數 :   命令關鍵字參數d:4,  多餘的關鍵字參數:value1和value2
>>> 1 我是outer函數,接收外部傳進來的old :         <function old at 0x00000000024FAA60>
>>> 1 我是outer函數,接收外部傳進來的old的參數 :   普通參數a=1, 默認參數b=22, 多餘的普通參數:args1和args2
>>> 1 我是outer函數,接收外部傳進來的old的參數 :   命令關鍵字參數d:4, 多餘的關鍵字參數:value1和value2
>>> 2 我是old函數 普通參數a=1, 默認參數b=22, 多餘的普通參數:args1和args2,命令關鍵字參數d:4, 多餘的關鍵字參數:value1和value2
>>> 3 我是outer函數,我在old函數後顯示
>>> 3 我是outer函數,我在old函數後顯示


  • 用帶參數的裝飾器函數   對   無參數原函數   進行修飾

def kuozhan(can_shu):
    def outer(f):
        tmp = can_shu
    	def inner1():
    		print("1 我是outer函數裏的inner1,接收外部傳進來的old :",f)
    		f()
    		print("3 我是outer函數裏的inner1,我在old函數後顯示")
    	
    	def inner2():
    	    print("1 我是outer函數裏的inner2,接收外部傳進來的old :",f)
    		f()
    		print("3 我是outer函數裏的inner2,我在old函數後顯示")
    	if tmp == 1:
    	    return inner1
    	else:
    	    return inner2

@kuozhan(2)                          # old = kuozhan(2)(old)    ==>      old = outer(old)
def old():
	print("2 我是old函數")
                                                
old()

>>> 1 我是outer函數裏的inner2,接收外部傳進來的old : <function old at 0x0000000001E8ABF8>
>>> 2 我是old函數
>>> 3 我是outer函數裏的inner2,我在old函數後顯示


  • 用帶參數的裝飾器函數   對   有參數原函數   進行修飾

def kuozhan(can_shu):
    def outer(f):
        tmp = can_shu
    	def inner1(var):
    		print("1 我是outer函數裏的inner1,接收外部傳進來的old :",f)
    		print("1  我是outer函數裏的inner1,接收外部傳進來的old的參數 :",var)
    		f(var)
    		print("3 我是outer函數裏的inner1,我在old函數後顯示")
    	
    	def inner2(var):
    	    print("1 我是outer函數裏的inner2,接收外部傳進來的old :",f)
    	    print("1  我是outer函數裏的inner2,接收外部傳進來的old的參數 :",var)
    		f(var)
    		print("3 我是outer函數裏的inner2,我在old函數後顯示")
    	if tmp == 1:
    	    return inner1
    	else:
    	    return inner2
    return outer

@kuozhan(2)                         # old = kuozhan(2)(old)    ==>      old = outer(old)
def old(var):
	print("2 我是old函數","參數: ",var)
var = "音樂"                                              
old(var)

>>> 1 我是outer函數裏的inner2,接收外部傳進來的old :        <function old at 0x00000000021CABF8>
>>> 1 我是outer函數裏的inner2,接收外部傳進來的old的參數 :  音樂
>>> 2 我是old函數      參數:  音樂
>>> 3 我是outer函數裏的inner2,我在old函數後顯示


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章