目錄
定義和傳遞參數
parameters 和arguments 之間的區別是什麼?
首頁 後端開發 Python教學 Python中函式參數傳遞方法*args, **kwargs,還有其他

Python中函式參數傳遞方法*args, **kwargs,還有其他

Apr 13, 2023 am 09:58 AM
python 傳遞參數

本文將討論Python的函數參數。我們將了解args和**kwargs,/和的都是什麼,雖然這個問題是一個基本的python問題,但是在我們寫程式碼時會經常遇到,例如timm中就大量使用了這樣的參數傳遞方式。

Python中函式參數傳遞方法*args, **kwargs,還有其他

定義和傳遞參數

parameters 和arguments 之間的區別是什麼?

許多人交替使用這些術語,但它們是有區別的:

  • Parameters 是函數定義中定義的名稱
  • Arguments是傳遞給函數的值

Python中函式參數傳遞方法*args, **kwargs,還有其他

紅色的是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.cn
登入後複製

3、如果想只接受關鍵字參數,那怎麼設計

可以強制函數只接受關鍵字參數。

 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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
4 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1670
14
CakePHP 教程
1428
52
Laravel 教程
1329
25
PHP教程
1273
29
C# 教程
1256
24
PHP和Python:解釋了不同的範例 PHP和Python:解釋了不同的範例 Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

在PHP和Python之間進行選擇:指南 在PHP和Python之間進行選擇:指南 Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

sublime怎麼運行代碼python sublime怎麼運行代碼python Apr 16, 2025 am 08:48 AM

在 Sublime Text 中運行 Python 代碼,需先安裝 Python 插件,再創建 .py 文件並編寫代碼,最後按 Ctrl B 運行代碼,輸出會在控制台中顯示。

PHP和Python:深入了解他們的歷史 PHP和Python:深入了解他們的歷史 Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

Python vs. JavaScript:學習曲線和易用性 Python vs. JavaScript:學習曲線和易用性 Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Golang vs. Python:性能和可伸縮性 Golang vs. Python:性能和可伸縮性 Apr 19, 2025 am 12:18 AM

Golang在性能和可擴展性方面優於Python。 1)Golang的編譯型特性和高效並發模型使其在高並發場景下表現出色。 2)Python作為解釋型語言,執行速度較慢,但通過工具如Cython可優化性能。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

notepad 怎麼運行python notepad 怎麼運行python Apr 16, 2025 pm 07:33 PM

在 Notepad 中運行 Python 代碼需要安裝 Python 可執行文件和 NppExec 插件。安裝 Python 並為其添加 PATH 後,在 NppExec 插件中配置命令為“python”、參數為“{CURRENT_DIRECTORY}{FILE_NAME}”,即可在 Notepad 中通過快捷鍵“F6”運行 Python 代碼。

See all articles