小編寫這篇文章的主要目的,主要是來給大家介紹,關于python中,相關語法問題的解答,比如在python,我們會遇到閉包和裝飾器不會用的情況,那么,下文就會來給大家做一個詳細的解答。
*args與**kwarsg及閉包和裝飾器
過程
先理解閉包,再理解裝飾器,不要忘了不定長參數
deffunc(): msg='111' deffunc1(): print(msg) returnfunc1 """
1-理解閉包 閉包即內部函數調用外部函數作用域里面的變量 比如func1就是一個閉包函數 """ func()()#這里實際上是func1() """ 2-裝飾器 fn是被裝飾的目標函數 2.1-僅僅只是傳遞函數名的裝飾器[基本不會用到] 2.2-裝飾帶有參數的函數 2.3-裝飾帶有返回值的函數 2.4-裝飾參數不確定的函數[可歸類到裝飾帶有參數的函數里面] 2.5-裝飾器本身攜帶參數 """
defdecorator(fn): defwrapper(): print("添加的功能,裝飾不帶有參數的函數") returnfn() returnwrapper @decorator deftest(): print("原有功能") test()#實際上是decorator(test) defdecorator1(fn): defwrapper(n1,n2): print("添加的功能,裝飾帶有參數的函數") returnfn(n1,n2) returnwrapper @decorator1 deftest1(a,b): print("a+b=%s"%(a+b)) print("原有功能") test1(1,2)#實際上是decorator1(test1(1,2)) defdecoretor2(fn): defwrapper(): print("添加的功能,裝飾帶有返回值的函數") res=fn() returnres returnwrapper @decoretor2 deftest2(): print("原有功能") return"返回值001" a=test2()#實際是decorator2(test2) print(a) defdecorator3(fn): defwarpper(*args,**kwargs): print("添加的功能,裝飾不定長參數的函數") returnfn(*args,**kwargs) returnwarpper @decorator3 deftest3(n1,n2,n3): print("原有功能") print(n1+n2+n3) test3(1,2,3)#實際上是decorator1(test1(1,2,3)) defdecorator4(home): deffunc_1(fn): defwrapper(*args,**kwargs): print("裝飾器本身攜帶參數") print("目前家在%s"%(home)) returnfn(*args,**kwargs) returnwrapper returnfunc_1 @decorator4(home='wuhan') deftest4(n1,n2,n3): print("原有功能") print(n1+n2+n3) #test3(1,2,3)=decorator3(home="武漢")(test(1,2,3))() """
1-先調用decorator3(home="wuhan")
2-執行func_1(test(1,2,3))#到這里其實就和前面的裝飾器一樣
3-執行wrapper
4-執行test(1,2,3)
"""
test4(1,2,3)
Pythonfun(*args,**kwargs)中*args,**kwargs參數含義及用法
1.Python函數中的兩種參數
我們知道,在Python中有兩種參數
位置參數(positionalargument):位置參數只能由參數位置決定
關鍵詞參數(keywordargument):關鍵詞參數只需要用keyword=somekey的方法即可傳參
位置參數只能由參數位置決定。這也就決定了位置參數一定要在前面,否則關鍵詞參數數量的變化都會使得位置無法判斷。
2.理解函數調用中的*
*的作用是將tuple或者list中的元素進行unpack,分開傳入,作為多個參數。
deffunc(a,b,c) print(a,b,c) alist=[1,2,3]#這里alist的長度必須和函數中參數的個數相同,否則會報錯 func(*alist) #等同于func(1,2,3) 123
2.1*做了什么
它拆開數列alist的數值作為位置參數,并把這些位置參數傳給函數func來調用。
因此拆數列、傳位置參數意味著func(*alist)與func(1,2,3)是等效的,因為alist=[1,2,3]。
3.理解函數調用中的**
**的作用是unpack字典,并將字典中的數據項作為鍵值參數傳給函數。
為了更好的理解舉幾個例子:
deffunc(a,b,c): print(a,b,c) if__name__=="__main__": dic={'b':2,'c':3} func(1,b=2,c=3) func(1,**dic) 123 123
4.理解函數調用中的*args和**kwargs
kwargs是keywordargument的縮寫,args就是argument。常見的是*args在**kwargs前面。
這兩個的用途和效果如下:
defthis_fun(a,b,*args,**kwargs): """ 在這個函數定義中,參數”a,b”代表”常規參數列表”。 args接收元組作為位置參數,而非是常見的參數列表 """ print(a,b) print(args) print(kwargs) if__name__='__main__' this_fun(0,1,2,3,index1=11,index2=22) 0,1 (2,3) {'index2':22,'index1':11}
也就是說,第一中不定的參數形式把剩下的沒有關鍵字的參數收起來形成一個tuple,而第二種把有關鍵字的收起來做成一個字典。
5.實例說明args,kwargs的應用場景
5.1子類傳參給父類方法
在任何時候繼承類和重寫方法的,我們應當用到args,kwargs將接收到的位置參數和鍵值參數給父類方法。通過實例我們更好的理解
classModel(object): def__init__(self,name): self.name=name defsave(self,force_update=False,force_insert=False): ifforce_updateandforce_insert: raiseValueError("Cannotperformbothoperations") ifforce_update: print("Updatedanexistingrecord") ifforce_insert: print("Createdanewrecord")
定義一個類,我們可以創建類的對象,類的對象有一個方法save().假設類的對象可以通過save()方法保存到數據庫中。通過函數save()參數來決定是否在數據庫中創建一條記錄或者更新現存的記錄。
構造一個新類,類有Model的行為,但只有符合某些條件才會保存這個類的對象。這個新類繼承Model,重寫Model的save()
classChildModel(Model): defsave(self,*args,**kwargs): ifself.name=='abcd': super(ChildModel,self).save(*args,**kwargs) else: returnNone
實際上對應的保存動作發生在’Model’的save方法中。所以我們調用子類的的save()方法而非’Model’的方法.子類ChildModel的save()接收任何父類save()需要的參數,并傳給父類方法。因此,子類save()方法參數列表中有*args和**kwargs,它們可以接收任意位置參數或鍵值參數,常規參數列表除外。
下面創建ChildModel實體并調用save方法:
c=ChildModel('abcd') c.save(force_insert=True) c.save(force_update=True) #結果 Createdanewrecord Updatedanexistingrecord
這里傳參數給對象的save()方法。調用的是子類的save(),它接收一個包含關鍵字參數kwargs的字典。然后,它使用**將字典作為關鍵字參數unpack,然后將其傳遞給超類save()。因此,超類save()獲得關鍵字參數force_insert并執行相應的操作。
5.2*args實現sum
defmy_sum(*args): res=0 forvalinargs: res+=val returnres l1=[4,8] l2=[1,2,3] print(my_sum(*l1)) #12 print(my_sum(*l2)) #6 print(my_sum(4,5,6)) #15
綜上所述,就為大家介紹到這里了,希望可以為大家帶來幫助。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/127833.html
摘要:理解的函數基礎要搞好深入淺出原型使用原型模型,雖然這經常被當作缺點提及,但是只要善于運用,其實基于原型的繼承模型比傳統的類繼承還要強大。中文指南基本操作指南二繼續熟悉的幾對方法,包括,,。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。 怎樣使用 this 因為本人屬于偽前端,因此文中只看懂了 8 成左右,希望能夠給大家帶來幫助....(據說是阿里的前端妹子寫的) this 的值到底...
摘要:一積累中如何快速查看包中的源碼最常用的大開發快捷鍵技巧將對象保存到文件中從文件中讀取對象中的用法的配置詳解和代碼的格式詳解格式化內容設置生成詳解注釋規范中設置內存調試的小知識單步執行命令的區別的動態代理機制詳解內容有瑕疵,樓指正泛型繼承的幾 一、積累 1.JAVA Eclipse中如何快速查看jar包中 的class源碼 最常用的15大Eclipse開發快捷鍵技巧 Java將對象保存到...
摘要:一積累中如何快速查看包中的源碼最常用的大開發快捷鍵技巧將對象保存到文件中從文件中讀取對象中的用法的配置詳解和代碼的格式詳解格式化內容設置生成詳解注釋規范中設置內存調試的小知識單步執行命令的區別的動態代理機制詳解內容有瑕疵,樓指正泛型繼承的幾 一、積累 1.JAVA Eclipse中如何快速查看jar包中 的class源碼 最常用的15大Eclipse開發快捷鍵技巧 Java將對象保存到...
摘要:在代碼執行時,對應的作用域鏈常常是保持靜態的。當語句執行完畢后,會把作用域鏈恢復到原始狀態。在全局作用域中創建的函數,其作用域鏈會自動成為全局作用域中的一員。 列表項目 前言 學習了javascript已經很久了,關于這個語言中的這兩個特性也是早已耳熟能詳,但是在實際的使用的過程中或者是遇到相關的問題的時候,還是不能很好的解決。因此我覺得很有必要深入的學習并且記錄這個問題,以便在今后的...
閱讀 911·2023-01-14 11:38
閱讀 878·2023-01-14 11:04
閱讀 740·2023-01-14 10:48
閱讀 1982·2023-01-14 10:34
閱讀 942·2023-01-14 10:24
閱讀 819·2023-01-14 10:18
閱讀 499·2023-01-14 10:09
閱讀 572·2023-01-14 10:02