網(wǎng)站首頁 編程語言 正文
*args與**kwarsg及閉包和裝飾器
過程
先理解閉包,再理解裝飾器,不要忘了不定長參數(shù)
def func():
msg = '111'
def func1():
print(msg)
return func1
"""
1-理解閉包
閉包即內(nèi)部函數(shù)調(diào)用外部函數(shù)作用域里面的變量
比如func1就是一個(gè)閉包函數(shù)
"""
func()()# 這里實(shí)際上是func1()
"""
2-裝飾器
fn是被裝飾的目標(biāo)函數(shù)
2.1-僅僅只是傳遞函數(shù)名的裝飾器[基本不會用到]
2.2-裝飾帶有參數(shù)的函數(shù)
2.3-裝飾帶有返回值的函數(shù)
2.4-裝飾參數(shù)不確定的函數(shù)[可歸類到裝飾帶有參數(shù)的函數(shù)里面]
2.5-裝飾器本身攜帶參數(shù)
"""
def decorator(fn):
def wrapper():
print("添加的功能,裝飾不帶有參數(shù)的函數(shù)")
return fn()
return wrapper
@decorator
def test():
print("原有功能")
test()# 實(shí)際上是decorator(test)
def decorator1(fn):
def wrapper(n1,n2):
print("添加的功能,裝飾帶有參數(shù)的函數(shù)")
return fn(n1,n2)
return wrapper
@decorator1
def test1(a,b):
print("a+b=%s"%(a+b))
print("原有功能")
test1(1,2)# 實(shí)際上是decorator1(test1(1,2))
def decoretor2(fn):
def wrapper():
print("添加的功能,裝飾帶有返回值的函數(shù)")
res = fn()
return res
return wrapper
@decoretor2
def test2():
print("原有功能")
return "返回值001"
a = test2() # 實(shí)際是decorator2(test2)
print(a)
def decorator3(fn):
def warpper(*args,**kwargs):
print("添加的功能,裝飾不定長參數(shù)的函數(shù)")
return fn(*args,**kwargs)
return warpper
@decorator3
def test3(n1,n2,n3):
print("原有功能")
print(n1+n2+n3)
test3(1,2,3)# 實(shí)際上是decorator1(test1(1,2,3))
def decorator4(home):
def func_1(fn):
def wrapper(*args,**kwargs):
print("裝飾器本身攜帶參數(shù)")
print("目前家在%s"%(home))
return fn(*args,**kwargs)
return wrapper
return func_1
@decorator4(home='wuhan')
def test4(n1,n2,n3):
print("原有功能")
print(n1+n2+n3)
# test3(1,2,3)=decorator3(home="武漢")(test(1,2,3))()
"""
1-先調(diào)用decorator3(home="wuhan")
2-執(zhí)行func_1(test(1,2,3)) # 到這里其實(shí)就和前面的裝飾器一樣
3-執(zhí)行wrapper
4-執(zhí)行test(1,2,3)
"""
test4(1,2,3)
Python fun(*args,**kwargs)中*args,**kwargs參數(shù)含義及用法
1. Python函數(shù)中的兩種參數(shù)
我們知道,在Python中有兩種參數(shù)
- 位置參數(shù)(positional argument): 位置參數(shù)只能由參數(shù)位置決定
- 關(guān)鍵詞參數(shù)(keyword argument): 關(guān)鍵詞參數(shù)只需要用 keyword = somekey 的方法即可傳參
位置參數(shù)只能由參數(shù)位置決定。這也就決定了位置參數(shù)一定要在前面,否則關(guān)鍵詞參數(shù)數(shù)量的變化都會使得位置無法判斷。
2. 理解函數(shù)調(diào)用中的*
*的作用是將tuple或者list中的元素進(jìn)行unpack,分開傳入,作為多個(gè)參數(shù)。
def func(a,b,c)
?? ?print(a,b,c)
alist = [1,2,3] # 這里alist的長度必須和函數(shù)中參數(shù)的個(gè)數(shù)相同,否則會報(bào)錯(cuò)
func(*alist) ?? ?# 等同于 func(1, 2, 3)
1 2 3
2.1 * 做了什么
它拆開數(shù)列alist的數(shù)值作為位置參數(shù),并把這些位置參數(shù)傳給函數(shù)func來調(diào)用。
因此拆數(shù)列、傳位置參數(shù)意味著func(*alist)與func(1,2,3)是等效的,因?yàn)?alist= [1,2,3]。
3. 理解函數(shù)調(diào)用中的**
**的作用是unpack字典,并將字典中的數(shù)據(jù)項(xiàng)作為鍵值參數(shù)傳給函數(shù)。
為了更好的理解舉幾個(gè)例子:
def func(a, b, c):
? ? print(a, b, c)
? ??
if __name__ == "__main__":
? ? dic = {'b': 2, 'c': 3}
? ? func(1, b=2, c=3)
? ? func(1, **dic)
1 2 3
1 2 3
4. 理解函數(shù)調(diào)用中的*args和**kwargs
kwargs是keyword argument的縮寫,args就是argument。常見的是*args 在 **kwargs 前面。
這兩個(gè)的用途和效果如下:
def this_fun(a,b,*args,**kwargs):
?? ?"""
?? ?在這個(gè)函數(shù)定義中,參數(shù)”a, b”代表”常規(guī)參數(shù)列表”。
?? ?args 接收元組作為位置參數(shù),而非是常見的參數(shù)列表
?? ?
?? ?"""
? ? 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}
也就是說,第一中不定的參數(shù)形式把剩下的沒有關(guān)鍵字的參數(shù)收起來形成一個(gè)tuple,而第二種把有關(guān)鍵字的收起來做成一個(gè)字典。
5. 實(shí)例說明args, kwargs的應(yīng)用場景
5.1 子類傳參給父類方法
在任何時(shí)候繼承類和重寫方法的,我們應(yīng)當(dāng)用到args, kwargs將接收到的位置參數(shù)和鍵值參數(shù)給父類方法。通過實(shí)例我們更好的理解
class Model(object):
? ? def __init__(self, name):
? ? ? ? self.name = name
? ? def save(self, force_update=False, force_insert=False):
? ? ? ? if force_update and force_insert:
? ? ? ? ? ? raise ValueError("Cannot perform both operations")
? ? ? ? if force_update:
? ? ? ? ? ? print("Updated an existing record")
? ? ? ? if force_insert:
? ? ? ? ? ? print("Created a new record")
定義一個(gè)類,我們可以創(chuàng)建類的對象,類的對象有一個(gè)方法save().假設(shè)類的對象可以通過save()方法保存到數(shù)據(jù)庫中。通過函數(shù)save()參數(shù)來決定是否在數(shù)據(jù)庫中創(chuàng)建一條記錄或者更新現(xiàn)存的記錄。
構(gòu)造一個(gè)新類,類有Model的行為,但只有符合某些條件才會保存這個(gè)類的對象。這個(gè)新類繼承Model,重寫Model的save()
class ChildModel(Model):
? ? def save(self, *args, **kwargs):
? ? ? ? if self.name == 'abcd':
? ? ? ? ? ? super(ChildModel, self).save(*args, **kwargs)
? ? ? ? else:
? ? ? ? ? ? return None
實(shí)際上對應(yīng)的保存動作發(fā)生在’Model’的save方法中。所以我們調(diào)用子類的的save()方法而非’Model’的方法.子類ChildModel的save()接收任何父類save()需要的參數(shù),并傳給父類方法。因此,子類save()方法參數(shù)列表中有*args和**kwargs,它們可以接收任意位置參數(shù)或鍵值參數(shù),常規(guī)參數(shù)列表除外。
下面創(chuàng)建ChildModel實(shí)體并調(diào)用save方法:
c=ChildModel('abcd')
c.save(force_insert=True)
c.save(force_update=True)
# 結(jié)果
Created a new record
Updated an existing record
這里傳參數(shù)給對象的save()方法。調(diào)用的是子類的save(), 它接收一個(gè)包含關(guān)鍵字參數(shù)kwargs的字典。然后,它使用**將字典作為關(guān)鍵字參數(shù)unpack,然后將其傳遞給超類save()。因此,超類save()獲得關(guān)鍵字參數(shù)force_insert并執(zhí)行相應(yīng)的操作。
5.2 *args 實(shí)現(xiàn)sum
def my_sum(*args):
?? ?res = 0
?? ?for val in args:
?? ??? ?res += val
?? ?return res
?? ?
l1 = [4, 8]
l2 = [1,2,3]
print(my_sum(*l1)) ?? ??? ?# 12
print(my_sum(*l2)) ?? ??? ?# 6
print(my_sum(4,5,6)) ?? ?# 15
原文鏈接:https://blog.csdn.net/Elephantpretty/article/details/124066408
相關(guān)推薦
- 2022-07-25 Android?嵌套?Intent?隱患及解決方案_Android
- 2023-05-23 手把手教你如何一眼分辨是C還是C++_C 語言
- 2022-06-08 記錄linux ens33網(wǎng)卡啟動失敗的問題
- 2022-10-07 Rust中的Struct使用示例詳解_相關(guān)技巧
- 2022-07-09 使用Jquery操作Cookies_jquery
- 2022-09-25 【報(bào)錯(cuò):No module named pytest】
- 2023-01-15 詳解Qt中線程的使用方法_C 語言
- 2022-07-16 Linux Redis-6.2.6單機(jī)部署
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支