1. 程式人生 > >python方法的引數理解

python方法的引數理解

關於方法的引數:位置引數—》預設引數—》可變引數—》關鍵字引數 | 可變關鍵字引數

–認真學習了一下python方法引數的用法,大概總結了以下內容,應該還是比較全面的–

定義引數:
      	引數的定義順序是:位置引數---》預設引數---》可變引數---》關鍵字引數   |   可變關鍵字引數
      	def   方法名(位置引數,預設引數 = 預設值,可變引數(*args) , 關鍵字引數(可以有關鍵字的預設
值)|  可變關鍵字引數(**kwargs) )
eg:
    def   test(arg1 , arg2 ,  arg3  =  5 , *args , arg4name = 6 , arg5name ,**kwargs):
        print('arg1:',arg1)  #位置引數1
        print('arg2:',arg2)  #位置引數2
        print('arg3:',arg3)  #預設引數
        print('args:',args)  #可變引數,結果是一個元組
        print('arg4name::',arg4name)  #關鍵字引數,帶有預設值
        print('arg5name:',arg5name)  #關鍵字引數,不帶預設值
        print('kwargs:',kwargs)   #可變關鍵字引數,結果是一個結合
    
   
    #test1   全部正常賦值
    test(1,2,3,4,5,arg4name=5,arg5name=6,arg5=8,arg6=9)
    #結果--》
        arg1: 1
        arg2: 2
        arg3: 3
        args: (4, 5)
        arg4name:: 5
        arg5name: 6
        kwargs: {'arg5': 8, 'arg6': 9}
            
    解釋:首先對於直接賦值的引數,方法預設按順序佔位,比如1佔位arg1,2佔位arg2,3佔位arg3,4和5
    預設佔位args可變引數,此時無論寫多少都會讓args照單全收,再後面就是按照關鍵字賦值的形式進
    行賦值,這個區間(args後面的關鍵字引數區間)就可以任意隨便的賦值,沒有先後之分,關鍵在每
    個鍵值要有值對應
    
    #test2  最少引數
    test(1,2,arg5name=3)
    #結果--》
        arg1: 1
        arg2: 2
        arg3: 5
        args: ()
        arg4name:: 6
        arg5name: 3
        kwargs: {}

    解釋:對於未知引數,必須全部賦值(任何形式賦值均可);對於關鍵字引數,如果關鍵字引數沒有
    預設值,那麼也必須賦值
    結論:所以當函式已經有位置引數和未賦值的關鍵字引數,那麼呼叫方法的時候,必須為他們傳值
    
    #test3  小小的昇華
    test(1,arg2=2,arg3=4,arg4=6,arg7=8,arg4name=9,arg5name=10,arg8=11)
    #結果--》
        arg1: 1
        arg2: 2
        arg3: 4
        args: ()
        arg4name:: 9
        arg5name: 10
        kwargs: {'arg4': 6, 'arg7': 8, 'arg8': 11}
    
    解釋:顯然這兒就會有疑問了,為什麼arg2,arg3可以用形似關鍵字的模式傳值呢?其實,這個只不過
    是傳值而已,它本身還是位置引數或者預設值引數。但是一定要記住,這種形似關鍵字引數  引數名
    ==值  和關鍵字引數賦值  都必須放到 佔位的位置引數後面,簡言之,呼叫方法的時候,帶有引數名
    賦值的必須寫到單獨一個賦值的後面
    為什麼會這樣呢?????其實吧,還是之前提到的佔位的問題,單獨一個數的賦值,會直接按照位
    置佔位,如果都是 引數名 == 值的形式,那就無所謂順序了,隨便寫到哪個位置都可以。但是該賦
    值的千萬要賦值(位置引數,未賦值的關鍵字引數)。
    
    所以,此時你會不會有一個想法:
        test(arg4=6,arg7=8,arg5name=10,arg8=11,arg1 =0,arg2=2,arg3=4,arg4name=9)  可以嗎?
        當然可以,沒有佔位就可以關鍵字形式的無序賦值
        
    
    #test4   *args,**kwargs的理解
    test(1,2,3,4,5,5,6,7,8,arg4name=7,arg5name=10,arg6name=11,arg7name=10)
    結果--》
        arg1: 1
        arg2: 2
        arg3: 3
        args: (4, 5, 5, 6, 7, 8)
        arg4name:: 7
        arg5name: 10
        kwargs: {'arg6name': 11, 'arg7name': 10}
        
    解釋:(1)有沒有發現,凡是關鍵字引數------必須用  引數名=引數值 的形式賦值;
        (2)當傳入的引數佔位位置引數和預設引數以後,多餘的引數會儲存到元組args中。
            當傳入的鍵值對引數( 引數名=引數值)除了引數必要的值以外,均會儲存到字典kwargs中。
            
            ------->其實,可變引數args以及前面的位置引數,預設引數 ,方法是將他們放到一個元組中進
            行操作的,args只是一個子集(理解即可)
            ------->關鍵字引數,方法是將他們放到一個字典中進行操作處理的,kwargs也只是一個子集
            (理解即可)
            
            所以也可以寫成這樣的形式:
            test(*(1,2,3,4,5,5,6,7,8),**{'arg4name':7,'arg5name':10,'arg6name':11,'arg8name'=10})  
                                    結果:--》
                                        arg1: 1
                                        arg2: 2
                                        arg3: 3
                                        args: (4, 5, 5, 6, 7, 8)
                                        arg4name:: 7
                                        arg5name: 10
                                        kwargs: {'arg6name': 11, 'arg8name': 10}
            同樣注意:關鍵字引數必須放到元組引數後面
            
            當然還有一種情況:test(**{'arg1':1,'arg2':2,'arg4name': 7, 'arg5name': 10, 
            'arg6name': 11, 'arg8name' : 10})
                            結果:
                                arg1: 1
                                arg2: 2
                                arg3: 5
                                args: ()
                                arg4name:: 7
                                arg5name: 10
                                kwargs: {'arg6name': 11, 'arg8name': 10}
            這樣也是可以的。這個就完全是用關鍵字引數進行賦值的,如果有元組引數寫入,必須寫到關
            鍵字引數前面
            
    #test5  關鍵字預設引數-----》很受歡迎
    形似列表的sort方法,內建函式sorted()方法,他們都有一個共同的key的關鍵字引數,(注意了:我
    們使用ctr+滑鼠左鍵 找到的他們的函式方法,並不是程式真正呼叫的底層,應該只是幫助理解用的)
    經過測試,key值在底層的程式碼中,肯定是利用的關鍵字預設值引數,而不是預設值引數
    
    ****這個用法非常普遍,也非常的實用,相比較預設值引數來說,更好用點吧。一般如果引數預設值
    為一個方法,最好用關鍵字預設引數,用多了,就感覺到了。
    #################################################################################
**錯誤案例:**
    error1:   代表性的缺少引數賦值
        test(1)
        
        解釋:很顯然,首先1佔位arg1引數,但是還有位置引數arg2和未賦值的關鍵字引數arg5name沒
        有賦值,報錯
    
    error2:  單個賦值數寫到了鍵值對賦值的後面
        test(1,arg4name = 8,arg5name = 9,3)
        
        解釋:這是一個寫出來pycharm軟體就會報錯的例子,我們本來的意思是讓1佔位arg1,3佔位arg2,
        但是這樣的寫法,python是不認同的,記住:帶有形似關鍵字賦值的表示式必須寫在只有一個值
        的後面(1,3必須寫在arg4name = 8,arg5name = 9的前面)