本文將討論Python的函數參數。我們將了解args和**kwargs,/和的都是什麼,雖然這個問題是一個基本的python問題,但是在我們寫程式碼時會經常遇到,例如timm中就大量使用了這樣的參數傳遞方式。
定義和傳遞參數
parameters 和arguments 之間的區別是什麼?
許多人交替使用這些術語,但它們是有區別的:
- Parameters 是函數定義中定義的名稱
- Arguments是傳遞給函數的值
紅色的是parameters , 綠色的是arguments。 傳遞參數的兩種方式我們可以按位置和關鍵字傳遞參數。在下面的範例中,我們將值hello作為位置參數傳遞。值world 用關鍵字傳遞的。
def the_func(greeting, thing): print(greeting + ' ' + thing) the_func('hello', thing='world')位置參數和kwargs(關鍵字參數)之間的差異在於傳遞位置參數的順序很重要。如果叫the_func('world', 'hello')它會印出world hello。傳遞kwargs的順序並不重要:
the_func('hello', 'world')# -> 'hello world' the_func('world', 'hello')# -> 'world hello' the_func(greeting='hello', thing='world') # -> 'hello world' the_func(thing='world', greeting='hello') # -> 'hello world' the_func('hello', thing='world')# -> 'hello world'只要kwarg在位置參數之後,就可以混合和匹配位置參數和關鍵字參數,以上就是我們在python教程中經常看到的內容,下面我們繼續。
函數參數
我們將示範6個函數參數傳遞的方法,這些方法能夠覆寫到所有的問題。 1、如何取得所有未捕獲的位置參數使用*args,讓它接收一個不指定數量的形參。def multiply(a, b, args): result = a * b for arg in args: result = result * arg return result
在這個函數中,我們通常定義前兩個參數(a和b)。然後使用
args將所有剩餘參數打包到一個元組中。可以把*看作是獲取到了其他沒有處理的參數,並將它們收集到一個名為“args”的元組變數中:multiply(1, 2)# returns 2 multiply(1, 2, 3, 4)# returns 24最後一次呼叫將值1賦給參數a,將2賦給參數b,並將arg變數填入(3,4)。由於這是一個元組,我們可以在函數中循環它並使用這些值進行乘法!2、如何獲得所有未捕獲的關鍵字參數與*args類似,這次是兩個星號**kwargs
def introduce(firstname, lastname, **kwargs): introduction = f"I am {firstname} {lastname}" for key, value in kwargs.items(): introduction += f" my {key} is {value} " return introduction**kwargs關鍵字會將所有不符合的關鍵字參數儲存在一個名為kwargs的字典中。然後可以像上面的函數一樣存取這個字典。
print(introduce(firstname='mike', lastname='huls')) # returns "I am mike huls" print(introduce(firstname='mike', lastname='huls', age=33, website='mikehuls.com')) # I am mike huls my age is 33 my website is overfit.cn3、如果想只接受關鍵字參數,那怎麼設計可以強制函數只接受關鍵字參數。
def transfer_money(*, from_account:str, to_account:str, amount:int):
print(f'Transfering ${amount} FORM {from_account} to {to_account}')
transfer_money(from_account='1234', to_account='6578', amount=9999)
# won't work: TypeError: transfer_money() takes 0 positional arguments but 1 positional argument (and 2 keyword-only arguments) were given
transfer_money('1234', to_account='6578', amount=9999)
# won't work: TypeError: transfer_money() takes 0 positional arguments but 3 were given
transfer_money('1234', '6578', 9999)
在上面的函數中,*星號獲得了所有不匹配的位置參數,但是並沒有一個變數來接受它,也就是被忽略了。 4、如何設計函數只接受位置參數下面是一個只允許位置參數的函數範例:
def the_func(arg1:str, arg2:str, /): print(f'provided {arg1=}, {arg2=}') # These work: the_func('num1', 'num2') the_func('num2', 'num1') # won't work: TypeError: the_func() got some positional-only arguments passed as keyword arguments: 'arg1, arg2' the_func(arg1='num1', arg2='num2') # won't work: TypeError: the_func() got some positional-only arguments passed as keyword arguments: 'arg2' the_func('num1', arg2='num2')函數定義中的/強制在它之前的所有參數都是位置參數。這並不意味著/後面的所有參數都必須是kwarg-only;這些可以是位置和關鍵字。 看到這個你一定會想,為什麼想要這個?這不會降低程式碼的可讀性嗎?,我也覺得你說的非常正確,當定義一個非常明確的函數時,不需要關鍵字參數來指定它的功能。例如:
def exceeds_100_bytes(x, /) -> bool: return x.__sizeof__() > 100 exceeds_100_bytes('a') exceeds_100_bytes({'a'})在這個例子中,正在檢查'a'的記憶體大小是否超過100位元組。因為這個x對我們來說他的名字不重要,在呼叫函數的時候不需要指定x= ' a '。例如我們最常用的len,如果你呼叫len(__obj=[]) 這樣看起來是不是有點呆萌,因為len是這麼定義的def len(__obj: Sized) -> int:# 5.混合和匹配作為一個例子,我們將看看前面討論過的len函數。這個函數只允許位置參數。我們將透過允許開發人員選擇是否計算重複項來擴展此函數,例如用kwargs傳遞這個關鍵字:
def len_new(x, /, *, no_duplicates=False): if (no_duplicates): return len(list(set([a for a in x]))) return len(x)
想計算變數x的len,只能按位置傳遞x形參的參數,因為它前面有一個/。 no_duplicate參數必須與關鍵字一起傳遞,因為它跟在
後面。讓我們看看這個函數都可以怎麼呼叫:print(len_new('aabbcc'))# returns 6 print(len_new('aabbcc', no_duplicates=True))# returns 3 print(len_new([1, 1, 2, 2, 3, 3], no_duplicates=False)) # returns 6 print(len_new([1, 1, 2, 2, 3, 3], no_duplicates=True))# returns 3 # Won't work: TypeError: len_() got some positional-only arguments passed as keyword arguments: 'x' print(len_new(x=[1, 1, 2, 2, 3, 3])) # Won't work: TypeError: len_new() takes 1 positional argument but 2 were given print(len_new([1, 1, 2, 2, 3, 3], True))6、最後把它們合在一起下面的函數是一個非常極端的例子,說明瞭如何組合前面討論的所有技術:它強制前兩個參數以位置方式傳遞,接下來的兩個參數可以以位置方式傳遞,並且帶有關鍵字,然後是兩個只有關鍵字的參數,然後我們用**kwargs捕獲剩下的未捕獲的參數。 ###
def the_func(pos_only1, pos_only2, /, pos_or_kw1, pos_or_kw2, *, kw1, kw2, **extra_kw): # cannot be passed kwarg <-- | --> can be passed 2 ways | --> can only be passed by kwarg print(f"{pos_only1=}, {pos_only2=}, {pos_or_kw1=}, {pos_or_kw2=}, {kw1=}, {kw2=}, {extra_kw=}")###呼叫方式如下:###
# works (pos_or_kw1 & pow_or_k2 can be passed positionally and by kwarg) pos_only1='pos1', pos_only2='pos2', pos_or_kw1='pk1', pos_or_kw2='pk2', kw1='kw1', kw2='kw2', extra_kw={} pos_only1='pos1', pos_only2='pos2', pos_or_kw1='pk1', pos_or_kw2='pk2', kw1='kw1', kw2='kw2', extra_kw={} pos_only1='pos1', pos_only2='pos2', pos_or_kw1='pk1', pos_or_kw2='pk2', kw1='kw1', kw2='kw2', extra_kw={'kw_extra1': 'extra_kw1'} # doesnt work, (pos1 and pos2 cannot be passed with kwarg) # the_func(pos_only1='pos1', pos_only2='pos2', pos_or_kw1='pk1', pos_or_kw2='pk2', kw1='kw1', kw2='kw2') # doesnt work, (kw1 and kw2 cannot be passed positionally) # the_func('pos1', 'pos2', 'pk1', 'pk2', 'kw1', 'kw2')###總結######看著很亂是吧,這就對了。因為python在設計時是一個很寬鬆的語言,並沒有那麼多的規範,用的人越多使用方法就越多,就變成了這樣。 ######那麼回到第一張圖:###############
def func(x,/,y,,z,**k):
(x,/,y,,z,**k):是函数的参数。总共有四个参数:
- x: 是一个常规参数,这意味着它可以按位置传递,也可以按关键字传递。
- /,: 是一个参数分隔符,将仅限位置的参数与其他参数分开。与前面的x结合,意味着x只能按位置传递。
- y: 时另一个常规参数。
- *: 是一个参数分隔符,用于分隔仅限位置参数和仅限关键字参数。它意味着后面的z只能通过关键字传递。
- z: 是一个仅限关键字的参数。
- **k: 这是一个参数,将所有剩余的关键字参数收集到一个名为' k '的字典中。
这样解释是不是就很明白了。
我们今天介绍的这个例子虽然在看源代码时没有遇到这么复杂的情况,但是在 面试 的时候还真有人问(虽然我觉得没啥用),所以最好还是知道一些,以免尴尬。
如果你忘记了,这里可以教你一个变通的办法,可以使用类似的回答:
上面的参数传递在开发时并不常用,因为对于开发规范来说,应该保证代码的可读性,我们这边遵循的开发规范是:
1、尽量不要在函数定义中将可变位置参数 *args 和可变关键字参数 **kwargs 放在一起,因为这样会让函数的调用方式变得不太直观。
2、在使用可变参数时,要保证函数的行为是可预测的。上面函数中的进行了太多的python语法糖,对于理解该函数的参数会造成很大的困惑,也就是可读性太差,我们在进行codereview(如果你了解什么是codereview就说,不了解就说组长检查)/组长merge代码 时会直接要求返工,所以我们在实际开发时是不会用这个的。
对于我阅读的开源代码,也都基本上使用的是 **kwargs这种情况(这里可以举两个例子),还没有看到有人写这么乱的代码,我想要是写这样的代码估计开源的人也会被人吐糟(这里自己可以自行延伸),所以这些参数传递的规则我在学习的时候看到过,但是实际中没见过真正使用,就不太记住了。
回到本文,我们介绍了设计函数参数的所有方法,并了解了如何混合和匹配它们,虽然后面几个内容可能你一辈子也不会用到,但是了解一下也是好的,因为万一呢。
以上是Python中函式參數傳遞方法*args, **kwargs,還有其他的詳細內容。更多資訊請關注PHP中文網其他相關文章!

Python的靈活性體現在多範式支持和動態類型系統,易用性則源於語法簡潔和豐富的標準庫。 1.靈活性:支持面向對象、函數式和過程式編程,動態類型系統提高開發效率。 2.易用性:語法接近自然語言,標準庫涵蓋廣泛功能,簡化開發過程。

Python因其簡潔與強大而備受青睞,適用於從初學者到高級開發者的各種需求。其多功能性體現在:1)易學易用,語法簡單;2)豐富的庫和框架,如NumPy、Pandas等;3)跨平台支持,可在多種操作系統上運行;4)適合腳本和自動化任務,提升工作效率。

可以,在每天花費兩個小時的時間內學會Python。 1.制定合理的學習計劃,2.選擇合適的學習資源,3.通過實踐鞏固所學知識,這些步驟能幫助你在短時間內掌握Python。

Python適合快速開發和數據處理,而C 適合高性能和底層控制。 1)Python易用,語法簡潔,適用於數據科學和Web開發。 2)C 性能高,控制精確,常用於遊戲和系統編程。

學習Python所需時間因人而異,主要受之前的編程經驗、學習動機、學習資源和方法及學習節奏的影響。設定現實的學習目標並通過實踐項目學習效果最佳。

Python在自動化、腳本編寫和任務管理中表現出色。 1)自動化:通過標準庫如os、shutil實現文件備份。 2)腳本編寫:使用psutil庫監控系統資源。 3)任務管理:利用schedule庫調度任務。 Python的易用性和豐富庫支持使其在這些領域中成為首選工具。

要在有限的時間內最大化學習Python的效率,可以使用Python的datetime、time和schedule模塊。 1.datetime模塊用於記錄和規劃學習時間。 2.time模塊幫助設置學習和休息時間。 3.schedule模塊自動化安排每週學習任務。

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

禪工作室 13.0.1
強大的PHP整合開發環境

WebStorm Mac版
好用的JavaScript開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)